简单的一般性误解

本文关键字:误解 一般性 简单 | 更新日期: 2023-09-27 17:50:31

你能帮我解释一下这种情况下的错误吗?

public interface IGeneralInterface
{
}

public class A : IGeneralInterface
{
}
public class B : IGeneralInterface
{
}
public class SomeClass<TGenericType> where TGenericType : IGeneralInterface
{
    private TGenericType internalValue;
    public SomeClass(TGenericType InitValue)
    {
        internalValue = InitValue;
    }
    public TGenericType CreateAnother()
    {
       TGenericType val1 = new B();   //Error here: class B() could not be converted to TGenericType
       return val1;
    }
}

即使我将SomeClass<T>构建为

SomeClass<IGeneralInterface> someClass = new SomeClass<IGeneralInterface>();

I显式传递基接口以包含所有(?)大小写,但它仍然抛出错误

简单的一般性误解

变化

 TGenericType val1 = new B();   //Error here: class B() could not be converted to TGenericType

  IGeneralInterface val1 = new B();   

您正在尝试将IGeneralInterface类型转换为TGenericType,这是错误的原因。

TGenericType可能有其他约束,比如它继承ISpecificInterfaceB没有继承。在这种情况下,赋值变为无效。

的例子:

public class SomeClass< TGenericType> where TGenericType : IGeneralInterface, ISpecificInterface
TGenericType val1 = new B(); // TGenericType should be ISpecificInterface also, B is not.

For上面运行。IGenericInterface应该比TGenericType更具体。

 public class SomeClass <IGenericInterface> 

或者,您可以使用is关键字来查找对象是否可分配给TGenericType,然后使用强制转换。

TGenericType val1 = default(TGenericType);
var val = new B();
if ( val is TGenericType)
{
  val1 = (TGenericType)val;
}

EDIT对于下面的注释

如何在运行时有额外的需求?我在编译器中输入的所有东西都列在这里

CreateAnother()创建类型为B的非泛型实例。看下面的例子

SomeClass<C> c = new SomeClass<C();
C another = c.CreateAnother(); // C is not assignable from B. (C is below). But It would be valid, if compiler did not flag the error
public class C : IGeneralInterface, IDisposable
{
}

为什么你认为new B()应该转换为TGenericType ?关于TGenericType我们唯一知道的是它实现了这个接口。

new B()类型不能转换为A为例。

我不知道你想要获得什么,但你可以将通用约束更改为:

public class SomeClass<TGenericType>
    where TGenericType : class, IGeneralInterface, new()

那么在create方法中写入new TGenericType()就可以了。

但是它将不再可能使用类型SomeClass<IGeneralInterface>,因为该接口没有可访问的无参数实例构造函数(当然,任何接口都不能有构造函数)。

代码中的问题是您正在声明变量

val1 
类型为 的

TGenericType

,然后尝试用不同类型的对象实例化它。

即使您已经声明了类的泛型类型必须在IGeneralInterface的继承层次结构中的条件,它们对于编译器来说也是不同的。我假设在这种情况下,您必须使用显式强制转换。