字典与类型作为值

时间:2013-06-26 02:25:27

标签: c# types dictionary

我需要一本能够做到这一点的词典:

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#版本)

2 个答案:

答案 0 :(得分: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)]; }
}

请注意,这将根据编译时类型添加项目,并且您将无法使用除精确类型之外的任何内容进行解析(而不是基本类型或可变转换类型)。

如果您想克服这些限制,请考虑使用像Autofac这样的完整IoC系统,它可以完成所有这些工作。

字典无法帮助,因为类型可兑换不是等价关系 例如,stringint都应计为object,但这两种类型并不相同。

答案 1 :(得分:2)

严格基于您的示例(即一种类型只能有一个条目),您可以实现这两种方式:

自定义词典

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

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