我有一个代码段:
public interface IMyInternalClass
{
}
public class MyInternalClass : IMyInternalClass
{
}
public interface IMyClass
{
T GetInternalObject<T>();
}
public class MyClass: IMyClass
{
private readonly MyInternalClass _internalObject;
public T GetInternalObject<T>()
{
return (T)(IMyInternalClass)_internalObject;
}
public MyClass(MyInternalClass internalObject)
{
_internalObject = internalObject;
}
}
GetInternalObject<T>
的用法:
IMyInternalClass internalObject = myClass?.GetInternalObject<IMyInternalClass>();
如果我尝试通过return (T)_internalObject;
使用显式转换-它将不起作用,并且将失败,并显示错误“ 无法将类型'MyInternalClass'转换为'T'”
因此,在不影响此代码示例的设计的情况下,为什么我要先将其显式转换为(IMyInternalClass)
呢?
还有另一个问题Cannot convert type: why is it necesssary to cast twice?,但没有关于接口使用情况的信息,例如 在这种情况下。
答案 0 :(得分:4)
为什么首先需要强制转换为
object
?
_internalObject
的类型为MyInternalClass
,而您正在尝试将其强制转换为T
。 T
可以是任何类型,因此编译器认为:“我敢肯定您肯定不能将MyInternalClass
转换为任何类型。”如果首先将其强制转换为object
,则编译器会认为“类型object
的值在运行时可以是任何类型,因此可以强制转换为任何类型。”
如果您不满意,这是使用该规范的另一种解释。
根据C#规范的第6.2.7节“涉及类型参数的显式转换”:
明确的参考转化
对于给定的类型参数T,存在以下显式转换:
- 从T的有效基类C到T,以及从C的任何基类C到T。在运行时,如果T是值类型,则转换将作为拆箱转换执行。否则,该转换将作为显式引用转换或标识转换执行。
- 从任何接口类型到T。在运行时,如果T是值类型,则转换将作为拆箱转换执行。否则,该转换将作为显式引用转换或标识转换执行。
- ...
T
的有效基类是object
,这就是为什么您可以执行此强制转换。
也就是说,您在这里所做的事情似乎是个坏主意。此代码非常不安全。您可以将任何类型传递给T
,但只有object
,IMyInternalClass
和MyInternalClass
之类的东西才能用于T
。
因此,这似乎是对泛型的滥用。您应该只返回MyInternalClass
或IMyInternalClass
:
public MyInternalClass GetInternalObject()
{
return _internalObject;
}
// or
public IMyInternalClass GetInternalObject()
{
return _internalObject;
}