2013-06-26 2 views
0

мне нужен словарь, который может сделать это:словарь с типом в качестве значения

Dictionary properties = new Dictionary(); 
properties.Add<PhysicalLogic>(new Projectile(velocity)); 

// at a later point 
PhysicalLogic logic = properties.Get<PhysicalLogic>(); 

я нашел this статью, в которой есть что-то похожее на то, что я хочу, но не совсем.

Unity3D не делает его своим методом GetComponent<>(), поэтому оно должно быть возможным: http://docs.unity3d.com/Documentation/ScriptReference/GameObject.GetComponent.html (Нажмите кнопку «JavaScript» выпадающий список, чтобы увидеть C# версии)

ответ

4

Существует нет встроенного класса, который делает это.

Вы можете написать его самостоятельно, обернув Dictionary<Type, object> и разливочный результат в Get<T>():

public class TypedDictionary { 
    private readonly Dictionary<Type, object> dict = new Dictionary<Type, object>(); 

    public void Add<T>(T item) { 
     dict.Add(typeof(T), item); 
    } 

    public T Get<T>() { return (T) dict[typeof(T)]; } 
} 

Обратите внимание, что это добавит элементов на основе их типа во время компиляции, и что вы не сможете решить используя что-либо иное, чем точный тип (в отличие от базовых типов или вариантов конвертируемых типов).

Если вы хотите преодолеть эти ограничения, рассмотрите возможность использования полной системы IoC, такой как Autofac, которая делает все это и многое другое.

Словарь там не может помочь, поскольку конвертируемость типов не является отношением эквивалентности.
Например, как string, так и int следует учитывать как object, но эти два типа не равны друг другу.

+0

Это отлично работает. В любом случае, я могу получить что-то вроде этого, чтобы работать с ним? properties.Add (someVar); –

1

Строго основываясь на вашем примере (т.е. один тип может иметь только одну запись), вы можете достичь этого два способа:

Пользовательский словарь

public class TypedDictionary : Dictionary<Type, object> 
{ 
    public void Add<T>(T value) 
    { 
     var type = typeof (T); 

     if (ContainsKey(type)) 
      this[type] = value; 
     else 
      Add(type, value); 
    } 

    public T Get<T>() 
    { 
     // Will throw KeyNotFoundException 
     return (T) this[typeof (T)]; 
    } 

    public bool TryGetValue<T>(out T value) 
    { 
     var type = typeof (T); 
     object intermediateResult; 

     if (TryGetValue(type, out intermediateResult)) 
     { 
      value = (T) intermediateResult; 
      return true; 
     } 

     value = default(T); 
     return false; 
    } 
} 

метод расширения

public static class TypedDictionaryExtension 
{ 
    public static void Add<T>(this Dictionary<Type, object> dictionary, T value) 
    { 
     var type = typeof (T); 

     if (dictionary.ContainsKey(type)) 
      dictionary[type] = value; 
     else 
      dictionary.Add(type, value); 
    } 

    public static T Get<T>(this Dictionary<Type, object> dictionary) 
    { 
     // Will throw KeyNotFoundException 
     return (T) dictionary[typeof (T)]; 
    } 

    public static bool TryGetValue<T>(this Dictionary<Type, object> dictionary, out T value) 
    { 
     var type = typeof (T); 
     object intermediateResult; 

     if (dictionary.TryGetValue(type, out intermediateResult)) 
     { 
      value = (T) intermediateResult; 
      return true; 
     } 

     value = default(T); 
     return false; 
    } 
} 

Первый метод более ясен, где, поскольку другой требует только определенного ic тип словаря.