将类型作为值的字典

本文关键字:字典 类型 | 更新日期: 2023-09-27 18:19:58

我需要一个可以做到这一点的字典:

Dictionary properties = new Dictionary();
properties.Add<PhysicalLogic>(new Projectile(velocity));
// at a later point
PhysicalLogic logic = properties.Get<PhysicalLogic>();

我发现这篇文章和我想要的有点相似,但不完全一样。

Unity3D使用他们的GetComponent<>()方法来实现这一点,因此它应该是可能的:http://docs.unity3d.com/Documentation/ScriptReference/GameObject.GetComponent.html(点击"JavaScript"下拉菜单查看C#版本)

将类型作为值的字典

没有内置类可以做到这一点。

您可以通过包装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)]; }
}

请注意,这将根据编译时类型添加项,并且您将无法使用除精确类型之外的任何其他类型(与基类型或可变转换类型相反)进行解析。

如果你想克服这些限制,可以考虑使用像Autofac这样的完整IoC系统,它可以做到这一切,甚至更多。

字典对此没有帮助,因为类型可转换性不是等价关系
例如,stringint都应算作object,但这两种类型并不相等。

严格根据您的示例(即一种类型只能有一个条目),您可以通过以下两种方式实现:

自定义词典

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;
    }
}

第一种方法更明确,因为另一种方法只需要特定类型的字典。