2012-08-23 2 views
2

반사를 사용하여 클래스 필드를 파악하고 채 웁니다. 현재 나는 Dictionary<,>의 인스턴스를 감지하고 채우기 위해 Dictionary<object,object>을 생성했습니다. 이후의 시도는 그러나이 작동하지 않는 유형을 변경하고 캐스팅 실패 :일반 사전을 알려진 유형으로 변환하는 방법은 무엇입니까?

// Looping through properties. Info is this isntance. 
// Check is a dictionary field. 
Dictionary<object, object> newDictionary = new Dictionary<object, object>(); 

// Populating the dictionary here from file. 
Type[] args = info.PropertyType.GetGenericArguments(); 
info.GetSetMethod().Invoke(data, new object[] 
    { 
     newDictionary.ToDictionary(k => Convert.ChangeType(k.Key, args[0]), 
            k => Convert.ChangeType(k.Value, args[1])) 
    }); 

어떤 아이디어? 감사.

+0

발견 한 사전의 일반적인 인스턴스를 만들어야합니다. 사용할 수없는 사전 인스턴스를 만들어야합니다. – user854301

답변

9

발견 한 유형의 설명서를 수동으로 만들어야합니다.

Type dictionary = typeof(Dictionary<,>); 
Type[] typeArgs = info.PropertyType.GetGenericArguments(); 

// Construct the type Dictionary<T1, T2>. 
Type constructed = dictionary.MakeGenericType(typeArgs); 
IDictionary newDictionary = (IDictionary)Activator.CreateInstance(constructed); 

// Populating the dictionary here from file. insert only typed values below 
newDictionary.Add(new object(), new object()); 


info.SetValue(data, newDictionary, null); 

downvoters를위한 증거.

static void Main(string[] args) 
    { 
     IDictionary<int, string> test = new Dictionary<int, string>(); 
     var castedDictionary = (IDictionary)test; 
     castedDictionary.Add(1, "hello"); 
     Console.Write(test.FirstOrDefault().Key); 
     Console.Write(test.FirstOrDefault().Value); 
     Console.ReadLine(); 
    } 

Dictionary<TKey, TValue>Dictionary<TKey, TValue> (Type dictionary = typeof(Dictionary<,>);)의 인스턴스를 생성 내 예 임에 IDictionary 구현합니다.

public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, 
    ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, 
    IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, 
    IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ISerializable, 
    IDeserializationCallback 
+0

사전을 이렇게 만들면 어떻게 채울 수 있습니까? 리플렉션을 통해 적절한 '추가'메소드를 호출 하시겠습니까? –

+0

간단한 newDictionary.Add (새 객체(), 새 객체()); 값을 유형으로 변환 할 수 있습니다. – user854301

+0

답이 잘못되었습니다! 'IDictionary '는'IDictionary'로부터 상속받지 않습니다. –

-1

당신이해야 할 일을하고 올바르게 입력 된 결과를내는 도우미 일반 클래스를 만듭니다. 그런 다음 런타임에 알려진 유형을 기반으로 클래스를 동적으로 인스턴스화합니다.

interface IHelper 
{ 
    object CreateDictionary(); 
} 

class Helper<TKey, TValue> : IHelper 
{ 
    public object CreateDictionary() 
    { 
     return (whatever).ToDictionary<TKey, TValue>(blah); 
    } 
} 

var h = Activator.CreateInstance(typeof(Helper<,>).MakeGenericType(yourKnownKeyType, yourKnownValueType)) as IHelper; 
info.SetValue(h.CreateDictionary()); 

매우 자주 발생하면 헬퍼 인스턴스를 캐시하여 매번 동적 인스턴스화의 영향을 피하십시오.

관련 문제