只知道密钥类型的键值对的集合

时间:2015-06-05 10:58:31

标签: c# generics icollection keyvaluepair

我想要一个键值对的集合类,其中ill知道实例化级别的键类型,但是只有在向集合添加新元素时才知道值类型。

考虑下面的代码段

public class Collection<TKey> where TKey : class
{
    public ICollection<KeyValuePair<TKey, IValue>> Col { get; set; }

    public void Add<TValue>(TKey key, TValue value) where TValue : IValue
    {
        Col.Add(new KeyValuePair<TKey, IValue>(key, value));
    }
}

public interface IValue
{
}

这很好,但是,上面代码的问题是插入类型必须是IValue类型,因为基元不是IValue的实现者,它们不能添加到列表。

我无法使用object取代TValue / IValue

修改

我想使用任何!键入键值对的值参数。如果可能,id就像要摆脱IValue。这是我可以获得编译代码的唯一方法

理想用法的一个例子如下:

    collection.Add("hello", 10);
    collection.Add("peter", "temp");
    collection.Add("hello1", new Foo());
    collection.Add("hello2", new Bar());

修改 我不能使用对象,因为对象不是所有对象都是可串行的,但是,我将实现更改为

class Program
{
    static void Main(string[] args)
    {
        var collection = new Collection<string>();
        collection.Add("hello", 10);
        collection.Add("peter", "temp");
        collection.Add("hello", new Bar());
    }
}

[Serializable]
public class KeyValuePair<TKey, TValue>
{
    private TKey _key;
    private TValue _value;

    public KeyValuePair(TKey key, TValue value)
    {
        _key = key;
        _value = value;
    }

    public TKey Key
    {
        get { return _key; }
        set { _key = value; }
    }

    public TValue Value
    {
        get { return _value; }
        set { _value = value; }
    }
}

public class Collection<TKey> where TKey : class
{
    public ICollection<KeyValuePair<TKey, ISerializable>> Col { get; set; }

    public void Add<TValue>(TKey key, TValue value) where TValue : ISerializable
    {
        Col.Add(new KeyValuePair<TKey, TValue>(key, value));
    }
}

编译器说argument type <TKey, TValue> is not assignable to parameter type <TKey, ISerializable>

2 个答案:

答案 0 :(得分:2)

事先注意:作为个人喜好,当我需要重复的键输入时,我倾向于使用字典表示具有唯一键的键/值对或multimap / ilookup。

如果您使用的是C#3.5或更早版本,则可以使用

var dic = new Dictionary<string, object>();  

假设您使用的是C#4,可以使用

var dic = new Dictionary<string, dynamic>();  

例如,人们喜欢用它来存储JSON数据。

你可以用Rx-Linq做很多事情,但我想说明你可以写:

var dic = new Dictionary<string, Lazy<string>>();

您可以在其中存储生成字符串的脚本。

答案 1 :(得分:1)

如果希望值包含基本类型,如int,float ect和自定义类型,则应使用object而不是IValue。

public class Collection<TKey> where TKey : class
{
    public ICollection<KeyValuePair<TKey, object>> Col { get; set; }

    public void Add(TKey key, object value)
    {
        Col.Add(new KeyValuePair<TKey, object>(key, value));
    }
}

此外,如果您希望在运行时快速进行基于哈希的键查找,则可能需要将ICollection<...>更改为Dictionary<TKey, object>