你能帮我理解那些情况下的错误吗?
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>();
我明确传递基接口以包含所有(?)个案,但它仍然会抛出错误
答案 0 :(得分:3)
更改
TGenericType val1 = new B(); //Error here: class B() could not be converted to TGenericType
要
IGeneralInterface val1 = new B();
您正在尝试将IGeneralInterface
版本TGenericType
添加到TGenericType
,这是导致错误的原因。
ISpecificInterface
可能有其他约束,例如它继承自B
不继承的public class SomeClass< TGenericType> where TGenericType : IGeneralInterface, ISpecificInterface
TGenericType val1 = new B(); // TGenericType should be ISpecificInterface also, B is not.
。在这种情况下,赋值变为无效。
示例:
IGenericInterface
以上运行。 TGenericType
应始终比 public class SomeClass <IGenericInterface>
更具体。
is
或者,您可以使用TGenericType
关键字来确定对象是否可以分配给TGenericType val1 = default(TGenericType);
var val = new B();
if ( val is TGenericType)
{
val1 = (TGenericType)val;
}
,然后使用转换。
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
{
}
的实例,该实例不是通用的。
以下为例
{{1}}
答案 1 :(得分:1)
为什么您认为new B()
应该可转换为TGenericType
?关于TGenericType
唯一知道的是它实现了接口。
例如,new B()
无法转换为A
类型。
我不知道你想要获得什么,但你可以将通用约束更改为:
public class SomeClass<TGenericType>
where TGenericType : class, IGeneralInterface, new()
然后可以在你的create方法中说new TGenericType()
。
但是不再可能使用类型SomeClass<IGeneralInterface>
,因为该接口没有可访问的无参数实例构造函数(当然,没有接口可以有构造函数)。
答案 2 :(得分:0)
代码中的问题是您要声明变量
val1
的类型
TGenericType
然后尝试通过不同类型的对象实例化它。
即使您已经声明了类的泛型类型必须位于IGeneralInterface
的继承层次结构中的条件,它们对于编译器也是不同的。我假设在这个设置中你必须使用显式的强制转换。