真实世界阵列协方差问题

时间:2011-06-10 18:01:59

标签: c# c#-4.0 covariance contravariance

我正在尝试创建一个DataTableColumn类的数组,但不幸的是我对此感到疯狂。 到现在为止,这是我试图做的没有任何成功

public interface IDataTableColumn<out TValue> {
    string Expression { get; }
    DataTableFilterType FilterType { get; }

    TValue Cast(string value);
}

public class DataTableColumn<TValue> : IDataTableColumn<TValue> {
    public DataTableColumn(string expression, DataTableFilterType filterType = DataTableFilterType.Equal) {
        Expression = expression;
        FilterType = filterType;
    }

    public string Expression { get; private set; }
    public DataTableFilterType FilterType { get; private set; }

    public TValue Cast(string value) {
        return value.As<TValue>();
    }
}

我的数组应该像

private readonly IDataTableColumn<object>[] _columns = {
    new DataTableColumn<int>("Id"), // ERROR
    new DataTableColumn<string>("Description", DataTableFilterType.StartsWith), // SUCCESS
    new DataTableColumn<DateTime?>("Date"), // ERROR
};

实际上像那样工作

private readonly dynamic[] _columns = {
    new DataTableColumn<int>("Id"),
    new DataTableColumn<string>("Description", DataTableFilterType.StartsWith),
    new DataTableColumn<DateTime?>("Date"),
};

我认为使用动态并不是最好的方法..有人会光明,请!

修改

该死的我忘记了错误

  

无法隐式转换类型   DataTableColumn&LT; int&gt;'至   “IDataTableColumn&LT;对象&gt;'。一个   存在显式转换(是吗?   错过演员?)

     

无法隐式转换类型   DataTableColumn&LT; System.DateTime的? &GT;”至   “IDataTableColumn&LT;对象&gt;'。一个   存在显式转换(是吗?   错过演员?)

1 个答案:

答案 0 :(得分:4)

我认为这是因为intDateTime是与object不一致的值类型(它们需要装箱)。编译代码时收到以下错误:

covar.cs(23,13): error CS0266: Cannot implicitly convert type
    'DataTableColumn<System.DateTime>' to 'IDataTableColumn<object>'.
    An explicit conversion exists (are you missing a cast?)

Per MSDN, "Variance in Generic Interfaces (C# and Visual Basic)"

  

仅针对参考类型支持通用接口的差异。值类型不支持方差。例如,IEnumerable<int>(Visual Basic中的IEnumerable(Of Integer))无法隐式转换为IEnumerable<object>(在Visual Basic中为IEnumerable(Of Object)),因为整数由值类型表示。

DataTableColumn<string>有效,因为它直接来自object