【问题标题】:Help using variance in C# 4.0帮助在 C# 4.0 中使用变体
【发布时间】:2009-09-27 16:54:01
【问题描述】:

这就是问题所在。我想创建一个包含配置数据的类。该数据由键/值对组成。一些示例:“hostName”="localhost"、“timeout”=1000 等。我最初的想法是将所有这些存储在通用字典中:

private Dictionary<string, ConfigurationItem<object>> Configuration = 
    new Dictionary<string, ConfigurationItem<object>>();

ConfigurationItem 类为:

public class ConfigurationItem<T>
{
    public string Name { get; set; }
    public T Value { get; set; }
}

希望能查询和设置配置如下:

int i = Configuration.Get<int>("Timeout");
Configuration.Set("Timeout", 1000);

很遗憾,我无法使用以下代码在配置字典中插入项目:

public void SetValue<T>(string key, ConfigurationItem<T> value)
{
        if (Configuration.ContainsKey(key.ToUpper()))
            Configuration[key.ToUpper()] = **value**;
        else
            Configuration.Add(key.ToUpper(),  **value**);
}

粗体部分显示错误:

无法将类型 ConfigurationItem 转换为 ConfigurationItem

我正在使用 C# 4.0,因为我希望使用新的方差特性来解决这个问题,但到目前为止还没有运气。如果需要更多信息,只需命名!感谢您的帮助!

【问题讨论】:

    标签: c# c#-4.0 variance


    【解决方案1】:

    C# 4.0 中的协变和逆变只适用于接口和委托。

    您必须在类型参数前面加上inout,具体取决于接口成员定义中类型参数的使用位置。

    例如:

    public interface IConfigurationItem<out T>
    {
        public string Name { get; set; }
        public T Value { get; set; }
    }
    

    因为IDictionary&lt;TKey,TValue&gt; 将其类型参数用于输入和输出,所以字典不是协变或逆变的。

    【讨论】:

      【解决方案2】:

      来自 C# 4.0 草案规范差异限制

      23.3 限制 协变和逆变类型参数只能在接口和委托类型上声明。仅当类型参数之间存在引用(或标识)转换时,协变和逆变才适用。例如,IEnumerable&lt;int&gt; 不是 IEnumerable&lt;object&gt;,因为从 int 到 object 的转换是装箱转换,而不是引用转换。

      【讨论】:

        【解决方案3】:

        您可以将您的 Dictionary 定义为私有 Dictionary,然后在从 Get 方法返回对象之前转换对象。

        【讨论】:

        • 感谢 Lance,这就是我接下来要做的,尽管我正在寻找一个不需要任何显式转换的解决方案。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-30
        • 2011-06-07
        • 2010-11-04
        • 1970-01-01
        • 1970-01-01
        • 2011-07-21
        相关资源
        最近更新 更多