문제

물체가 사전인지 테스트하는 방법이 있습니까?

메소드에서 목록 상자의 선택한 항목에서 값을 얻으려고합니다. 어떤 상황에서는 목록 상자가 사전에 묶여있을 수 있지만 컴파일 시간에는 알려지지 않았습니다.

나는 이것과 비슷한 일을하고 싶습니다 :

if (listBox.ItemsSource is Dictionary<??>)
{
    KeyValuePair<??> pair = (KeyValuePair<??>)listBox.SelectedItem;
    object value = pair.Value;
}

반사를 사용하여 런타임에 동적 으로이 작업을 수행하는 방법이 있습니까? 일반 유형과 함께 반사를 사용하고 키/값 매개 변수를 결정할 수 있지만 해당 값이 검색된 후 나머지를 수행 할 수있는 방법이 있는지 확실하지 않습니다.

도움이 되었습니까?

해결책

다음과 같은 것이어야합니다. 구문이 정확히 옳지 않을 수 있도록 답변 상자에 이것을 썼지 만 Wiki 편집 가능성이 있으므로 누구나 고칠 수 있습니다.

if (listBox.ItemsSource.IsGenericType && 
    typeof(IDictionary<,>).IsAssignableFrom(listBox.ItemsSource.GetGenericTypeDefinition()))
{
    var method = typeof(KeyValuePair<,>).GetProperty("Value").GetGetMethod();
    var item = method.Invoke(listBox.SelectedItem, null);
}

다른 팁

신경을 구현하는지 확인하십시오.

System.collections.idictionary의 정의를 참조하여 그것이 무엇을 주는지 확인하십시오.

if (listBox.ItemsSource is IDictionary)
{
    DictionaryEntry pair = (DictionaryEntry)listBox.SelectedItem;
    object value = pair.Value;
}

편집하다:keyvaluepair가 Dictionaryentry에 캐스트 할 수 없다는 것을 깨달았을 때의 대안

if (listBox.DataSource is IDictionary)
{
     listBox.ValueMember = "Value";
     object value = listBox.SelectedValue;
     listBox.ValueMember = ""; //If you need it to generally be empty.
}

이 솔루션은 반사를 사용하지만이 경우 Grunt 작업을 수행 할 필요는 없습니다. ListBox는 귀하를 위해 수행합니다. 또한 일반적으로 데이터 소스로 사전이있는 경우 항상 재설정을 방지하지 못할 수 있습니다.

나는이 질문이 몇 년 전에 질문을 받았다는 것을 알고 있지만 여전히 공개적으로 볼 수 있습니다.

이 주제와 이것에는 여기에 제안 된 사례가 거의 없었습니다.
유형이 사전인지 결정 [복제

하지만 불일치가 거의 없으므로 솔루션을 공유하고 싶습니다.

짧은 대답:

var dictionaryInterfaces = new[]
{
    typeof(IDictionary<,>),
    typeof(IDictionary),
    typeof(IReadOnlyDictionary<,>),
};

var dictionaries = collectionOfAnyTypeObjects
    .Where(d => d.GetType().GetInterfaces()
        .Any(t=> dictionaryInterfaces
            .Any(i=> i == t || t.IsGenericType && i == t.GetGenericTypeDefinition())))

더 긴 답변 :
나는 이것이 사람들이 실수를하는 이유라고 생각합니다.

//notice the difference between IDictionary (interface) and Dictionary (class)
typeof(IDictionary<,>).IsAssignableFrom(typeof(IDictionary<,>)) // true 
typeof(IDictionary<int, int>).IsAssignableFrom(typeof(IDictionary<int, int>)); // true

typeof(IDictionary<int, int>).IsAssignableFrom(typeof(Dictionary<int, int>)); // true
typeof(IDictionary<,>).IsAssignableFrom(typeof(Dictionary<,>)); // false!! in contrast with above line this is little bit unintuitive

그러니 우리에게 다음과 같은 유형이 있다고 가정 해 봅시다.

public class CustomReadOnlyDictionary : IReadOnlyDictionary<string, MyClass>
public class CustomGenericDictionary : IDictionary<string, MyClass>
public class CustomDictionary : IDictionary

그리고 이러한 사례 :

var dictionaries = new object[]
{
    new Dictionary<string, MyClass>(),
    new ReadOnlyDictionary<string, MyClass>(new Dictionary<string, MyClass>()),
    new CustomReadOnlyDictionary(),
    new CustomDictionary(),
    new CustomGenericDictionary()
};

따라서 .isassignablefrom () 메소드를 사용하면 :

var dictionaries2 = dictionaries.Where(d =>
    {
        var type = d.GetType();
        return type.IsGenericType && typeof(IDictionary<,>).IsAssignableFrom(type.GetGenericTypeDefinition());
    }); // count == 0!!

우리는 사례를 얻지 못할 것입니다

가장 좋은 방법은 모든 인터페이스를 얻고 사전 인터페이스인지 확인하는 것입니다.

var dictionaryInterfaces = new[]
{
    typeof(IDictionary<,>),
    typeof(IDictionary),
    typeof(IReadOnlyDictionary<,>),
};

var dictionaries2 = dictionaries
    .Where(d => d.GetType().GetInterfaces()
        .Any(t=> dictionaryInterfaces
            .Any(i=> i == t || t.IsGenericType && i == t.GetGenericTypeDefinition()))) // count == 5

당신은 그것이 구현되는지 확인할 수 있습니다 우아함. 당신은 그냥 사용하기 만하면됩니다 사전 수업.

당신은 조금 더 일반적인 것이고 대신 그것을 구현하는지 물어볼 수 있습니다. IDictionary. 그런 다음 KeyValue 컬렉션이 계속됩니다 Objects.

나는 경고가 자리에 있다고 믿는다.

객체가 '이것 또는 그게'인 경우 테스트 할 때 유형 시스템의 일부를 상환하고 있습니다 (일부). 첫 번째 '는 A'가 종종 두 번째로 신속하게 이어지고 곧 코드는 유형 검사로 가득 차 있으며, 이는 적어도 객체 지향 디자인에서 유형 시스템에 의해 매우 잘 처리되어야합니다.

물론, 나는 질문의 맥락에 대해 아무것도 모른다. 나는 우리 자신의 코드베이스에 2000 줄 파일을 알고 있으며, 50 개의 다른 객체를 문자열 변환으로 처리합니다 ... :(

if(typeof(IDictionary).IsAssignableFrom(listBox.ItemsSource.GetType()))
{

}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top