- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
更新:这与让它编译无关。问题是,为什么 C# 编译器在使用接口(interface)时允许转换,但当我使用实现相同接口(interface)的类时却无法确定类型。
我收到以下错误:
Cannot convert type 'Amber.BLL.iWeb.Session.AppSession' to 'TService'
代码如下:
public override TService GetService<TService>()
{
if ( typeof( TService ) == typeof( IAppSession ) )
{
AppSession session = new AppSession();
return (TService) session;
}
throw new Exception( String.Format(
"iWebFactoryProvider cannot create services of type '{0}'.",
typeof( TService ).Name ) );
}
碰巧,AppSession
类实现了IAppSession
接口(interface)。如果我更改实例化 AppSession
的代码行以使用该接口(interface),如下所示:
IAppSession session = new AppSession();
突然一切都编译好了。我还注意到,如果我这样做,它编译得很好:
AppSession session = new AppSession();
return (TService) (IAppSession) session;
以防万一,GetService() 覆盖了一个方法,其签名声明如下:
public virtual TService GetService<TService>() where TService : class
简而言之,我无法弄清楚这里应该有什么规则,以便我知道将来如何避免这种情况。为什么编译器乐于强制转换接口(interface),而不乐于强制转换接口(interface)的实现类?
我注意到 this question问了一个类似的问题,但答案不够详细,我无法理解它如何适用于我的情况。
最佳答案
Why does the C# compiler allow the cast when using an interface, but it can't figure out the type when I use a class that implements the same interface?
好问题。请考虑以下事项:
public interface I {}
public class D {} // Note that D does not even implement I!
public class E
{
public static M<T>(T t)
{
D d1 = (D)t; // Illegal
D d2 = (D)(object)t; // Legal
D d3 = (D)(I)t; // Legal
}
}
让我们将您的问题分成三个问题。
Why is the cast directly from
T
toD
illegal?
假设它是合法的。然后 E.M<D>(new D())
会工作得很好;我们投了 T
至 D
事实上它是一个D
,所以没问题。
现在假设我们创建一个完全不同的程序集:
class C
{
public static explicit operator D(C c) { whatever }
}
你调用E.M<C>(new C())
在那个集会中.. 你合理地期望会发生什么?您有一个 C
类型的对象, 它被转换为 D
,并且有一个来自 C
的显式转换运算符就在那里至 D
.大多数人会合理地期望会调用显式转换运算符。
但是编译器在编译 M
的主体时应该如何实现 将来有人可能会创建一个类 C
在一个完全不同的程序集中?编译器在编译时无法发出对转换运算符的调用 M
.所以我们有三个选择:
简而言之,我们的选择是 (1) 使泛型不一致,(2) 使泛型缓慢且不可预测,或 (3) 禁止已经在反对泛型的功能。这是一个容易做出的选择;我们选择了(3)。
如果你想要 (2),你可以在 C# 4 中拥有它; dynamic
在运行时再次启动编译器并计算是否存在显式转换运算符。
Why is the cast indirectly from
T
toD
via object legal?
因为现在没有用户定义的转换是相关的;从来没有用户定义的从对象到任何东西的转换。
Why is the cast indirectly from
T
toD
viaI
legal?
因为现在没有用户定义的转换是相关的;从来没有用户定义的从接口(interface)到任何东西的转换。
奖励问题:
But
D
does not even implementI
! What's up with that?
D
的派生类可能:
class F : D, I {}
...
E.M<D>(new F());
现在t
可以转换为 I
因为它可能实现I
, 和 I
可以转换为 D
因为它可能是F
.
如果D
是sealed
那么从 I
转换是不合法的至 D
因为那样就不可能有派生的 F
类型。
关于c# - C# 中的泛型 - 无法将 'classname' 转换为 'TGenericClass',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9501439/
我是一名优秀的程序员,十分优秀!