我正在寻找一种将对象转换为简单接口以及从简单接口派生的通用接口的方法。

这是我的示例:

interface INonGeneric
{

}

interface IGeneric<T> : INonGeneric where T : ITypeParameter
{
    T Build();
}

interface ITypeParameter
{

}

class TypeClass : ITypeParameter
{

}


这就是我尝试使用的设计。如果我对泛型的理解存在缺陷(我认为是有缺陷的),那么错误对于您将是显而易见的。

然后创建我要使用的类:

class MyClass : MyClassBase<TypeClass>
{
    public override TypeClass Build()
    {
        return new TypeClass();
    }
}

abstract class MyClassBase<T> : IGeneric<T> where T : ITypeParameter
{
    public abstract T Build();
}


然后,我尝试像这样投射它们:

void Main()
{
    var myClass = new MyClass();

    var cast1 = myClass as INonGeneric;
    if(cast1 != null) Console.WriteLine("cast 1 works!"); //THIS WORKS
    var cast2 = TestCast<ITypeParameter>(myClass);
    if(cast2 != null) Console.WriteLine("cast 2 works!"); //THIS DOES NOT WORK
}


任何帮助将不胜感激。

编辑:对不起,我忘了输入TestCast方法。这里是:

IGeneric<T> TestCast<T>(INonGeneric obj) where T : ITypeParameter
{
    return obj as IGeneric<T>;
}

最佳答案

由于协方差的考虑,这不起作用。
考虑此示例代码。

var liInt = new List<int>() { 1,2,3};
var liObj = List<object>(liInt);


在那之后,您可以将一些非整数值严重添加到liObj中,显然,这不行。

bool b = false;
liObj.Add(b);


为了避免这种情况,您应该隐式告诉您,仅在返回位置而不是输入中使用泛型类型。例如:

interface IGeneric<out T> : INonGeneric where T : ITypeParameter


有关更多信息,请参见下面的链接:
http://tomasp.net/blog/variance-explained.aspx/

10-05 23:09
查看更多