>我有以下代码
public interface IInterface
{
}
public class GenericClass<TSomeClass>
where TSomeClass : class
{
public TSomeClass SomeMethod(TSomeClass someClass = null)
{
return SomeClass.SomeClassStaticInstance; //ERROR:Cannot implicitly convert type 'SomeClass' to 'TSomeClass'
return (TSomeClass)SomeClass.SomeClassStaticInstance; //ERROR:Cannot convert type 'SomeClass' to 'TSomeClass'
return SomeClass.SomeClassStaticInstance as TSomeClass; //Works when "where TSomeClass : class" clause added
}
}
public class SomeClass : IInterface
{
public static SomeClass SomeClassStaticInstance = new SomeClass();
}
它会生成相应行的注释中记录的编译时错误。
我想知道为什么我不能只使用产生错误的第一行?SomeClass
实现了IInterface
但我不得不弄乱as
关键字。
我尝试将GenericClass<TSomeClass>
更改为GenericClass<out TSomeClass>
但随后我收到另一个编译时错误Only interface and delegate type parameters can be specified as variant.
即使我删除了where TSomeClass : class
子句,该错误仍然存在。
我错过了什么...它显然有效,因为我可以使用where TSomeClass : class
子句和return SomeClass.SomeClassStaticInstance as TSomeClass;
语句"强制它"!
我确实需要where TSomeClass : class
否则我会收到另一个编译时错误TSomeClass someClass = null
......A value of type '<null>' cannot be used as a default parameter because there are no standard conversions to type 'TSomeClass'
.
所以基本上是编译时错误一直向下!谢谢。
I would like to know why I can't just use the first line that generates an error? SomeClass implements IInterface but I have to mess around with the as keyword.
您必须使用(TSomeClass)YourInstance
因为语言旨在防止对转换泛型参数的任何假设。阅读更多。
因为无法预测参数类型的隐式转换 TSomeClass,除非您放置继承类型较少的约束,例如接口。应将约束更改为差异where TSomeClass : IInterface
。
使用as
键有效,因为如果类型不兼容,它将返回 null,这就是您需要class
约束的原因。将约束更改为接口后,as
语句将变为无效。
在工厂方法中,应返回IInterface
以便泛型类型参数可以接受直接强制转换。
我相信这会起作用:
public interface IInterface
{
}
public class GenericClass<TSomeClass>
where TSomeClass : IInterface
{
//Not sure what the input parameter is for?
public IInterface SomeMethod(TSomeClass someClass = null)
{
return SomeClass.SomeClassStaticInstance;
}
}
public class SomeClass : IInterface
{
public static IInterface SomeClassStaticInstance = new SomeClass();
}
然而,正如其他人所指出的,这里的问题实际上是在这种情况下使用泛型的用途 - 是否有更好的选择来构建你的代码?
很难从您给我们的结构中判断这样做的目的是什么。
目前你唯一的约束是TSomeClass
是一个类,所以如果你要用一个不是SomeClass
的类型或从它派生的类型来实例化GenericClass
,return SomeClass.SomeClassStaticInstance;
显然是行不通的。
例如:
var genericClass = new GenericClass<SomeRandomClass>(); // fine
var randomClass = genericClass.SomeMethod(new SomeRandomClass()); // not fine, a SomeClass is returned!
我不确定IInterface
目前在这一切中的位置?
也许你希望 SomeMethod 返回一个实现IInterface
的对象;如果是这样,你需要进一步约束你的泛型类型,并让你的方法返回一个IInterface
:
public class GenericClass<TSomeClass> where TSomeClass : class, IInterface
{
public IInterface SomeMethod(TSomeClass someClass = null)
{
return SomeClass.SomeClassStaticInstance; //This now compiles!
}
}
至于return SomeClass.SomeClassStaticInstance as TSomeClass;
最初为什么有效,这只是一个巧合。
as
是一个安全的强制转换运算符,如果尝试的转换失败,它将返回null
。由于TSomeClass
约束为类,因此null
返回值将有效。但是,如果您指定的泛型类型未SomeClass
,则始终返回null
。