【问题标题】:Any chance to cast legally?有机会合法投吗?
【发布时间】:2011-02-24 14:23:57
【问题描述】:

这是我第一次在这里发布问题,所以提前感谢任何会帮助我(也许还有其他人)的人。

今天我一直对 C# 4 中的协变和逆变感到困惑,但我真的看不出有任何可能做我想做的事。 注意:所有 NOT 都是为了解决特定问题,但我想知道是否有任何合法的方法(C# 4 中的全新 co/contra-variance)来解决它。 所以,不要发疯……

这里是示例代码:

public interface IBase<in T>
{
    T GetValue();
    ...
}


public class Readable<T> : IBase<T>
{
    public T GetValue() {/* */}
    ...
}


public class Writeable<T> : IBase<T>
{
    public T GetValue() {/* */}
    public void SetValue(T value) {/* */}
    ...
}


public class Program
{
    private List<IBase<object>> _collection = new List<IBase<object>>();


    public static void Main()
    {
        var p = new Program();

        p._collection.Add(new Readable<bool>());    //not allowed
    }
}

该集合应该能够托管任何 IBase 派生类,它们属于任何 T。 当然,我可以使用非泛型集合或列表,然后游戏就结束了。 另一个想法是有一个更通用的接口 IBaseCore,然后 IBase 继承自。 我的问题是:如果没有这些技巧,我可以实现拥有 IBase 的集合并添加任何 IBase 的项目吗?

谢谢大家。

【问题讨论】:

    标签: .net generics c#-4.0 covariance contravariance


    【解决方案1】:

    编辑:首先,您的方差对于IBase&lt;T&gt; 是错误的。它应该是out T(协变)而不是in T(逆变)。

    这里的问题只是泛型协变和逆变不适用于作为类型参数的值类型。所以你可以添加Readable&lt;string&gt;,但不能添加Readable&lt;bool&gt;

    一种选择是有一个非通用的基本接口:

    public interface IBase
    {
        object GetValueAsObject();
    }
    
    public interface IBase<out T> : IBase
    {
        T GetValue();
        ...
    }
    

    那么你可以有一个List&lt;IBase&gt;

    【讨论】:

    • 了不起的乔恩!...哇:今晚我睡不着了!
    • 是的,IBase 非泛型是一个想法。我不知道类型嵌套...无论如何非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2012-03-04
    • 2018-02-22
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    相关资源
    最近更新 更多