C#类型推理、泛型和接口

C#类型推理、泛型和接口,c#,C#,我在C#中的类型推断中发现了一些奇怪的东西 举个例子 我有一个接口 interface IInterface1 { } class Class1 : IInterface1 { } 和一个实现接口的类 interface IInterface1 { } class Class1 : IInterface1 { } 然后我有一个创建类的函数 static Class1 GetInstanceOfClass1() { return new Class1(); } 我想使用泛型函数,

我在C#中的类型推断中发现了一些奇怪的东西

举个例子

我有一个接口

interface IInterface1
{
}
class Class1 : IInterface1
{
}
和一个实现接口的类

interface IInterface1
{
}
class Class1 : IInterface1
{
}
然后我有一个创建类的函数

static Class1 GetInstanceOfClass1()
{
    return new Class1();
}
我想使用泛型函数,它将返回一个可枚举的

static IEnumerable<T> GetSomething<T>() where T : IInterface1
{
    yield return GetInstanceOfClass1();
}
错误消息如下所示

无法将类型“TypeExpression.Class1”转换为“T”

它不能像以前那样转换

嗯。我写的是

yield return (T)GetInstanceOfClass1();
yield return (IInterface1)GetInstanceOfClass1();
yield return (T)(IInterface1)GetInstanceOfClass1();
得到

无法将类型“TypeExpression.IIinterface1”隐式转换为“T”

它不能像以前那样转换

但如果我写的是

yield return (T)GetInstanceOfClass1();
yield return (IInterface1)GetInstanceOfClass1();
yield return (T)(IInterface1)GetInstanceOfClass1();
一切都好

有人能解释一下是什么错了,为什么代码最终被编译了吗


谢谢。

这是为了防止你自己射中自己的脚。就像你最终还是做了一样

如果你定义

interface IInterface2 : IInterface1 { }
class Class2 : IInterface1 { }
然后调用
GetSomething()
?它是一个有效的泛型类型参数,但是
Class1
没有实现
IInterface2

更糟糕的是,如果你定义

interface IInterface2 : IInterface1 { }
class Class2 : IInterface1 { }
然后调用
GetSomething()


您的设计被破坏了,您需要进一步考虑它,在您有一个实际可行的设计之前,不要继续处理编译器错误。

您的类型参数T保证实现
IInterface1
,但它与
Class1
的关系未指定

因此:

  • T可能不是
    Class1
    的超类,而且
    Class1
    也可能不是T=>
    (T)getInstanceOffClass1()的超类
  • 无法从返回t=>
    (IInterface1)GetInstanceOffClass1()的方法返回
    IInterface
  • 有效的方法是:

    当然,您可以将
    Class1
    转换为
    IInterface
    ,因为
    Class1
    实现了接口。 现在,由于T还实现了IInterface,它可能是有效的强制转换,也可能在运行时失败。 这类似于在编译时将任何对象转换为给定类型的方式,但如果对象的运行时类型错误,则它将在运行时失败

    例如


    这将编译,但在运行时失败。

    不能保证
    (T)(IInterface1)getInstanceOffClass1()在运行时不会中断。可以创建
    类NewClass1:IInterface1
    ;调用
    GetSomething()
    并获取异常。当您执行类型转换
    (T)(IInterface1)
    时,编译器信任您,但运行时不会