【问题标题】:Cast simple object to simple and generic Interface将简单对象转换为简单通用接口
【发布时间】:2018-10-16 09:20:08
【问题描述】:

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

这是我的例子:

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>;
}

【问题讨论】:

  • 我明白了,所以这一定意味着我需要将其更改为: class MyClass : MyClassBase { public override ITypeParameter Build() { return new TypeClass(); } }
  • 看看Covariance。如果您将接口定义更改为interface IGeneric&lt;out T&gt;,那么您将能够使用所需的演员表。
  • 是的,泛型中的out关键字可以让编译器知道接口中的类型T是协变的(之后就可以进行这样的转换)

标签: c# generics types parameters casting


【解决方案1】:

由于协方差问题,这不起作用。 考虑这个示例代码。

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/

【讨论】:

  • 谢谢,我现在更好地理解了这个问题。也感谢其他评论者。我现在设法为我的使用打下了坚实的基础。
猜你喜欢
  • 2021-07-15
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 2016-08-02
相关资源
最近更新 更多