我昨天偶然发现了这个奇怪的情况,它t as D
返回一个非空值,但(D)t
会导致编译器错误。
由于我很着急,所以我只是使用并继续,但我很t as D
好奇为什么演员表无效,因为. 谁能解释为什么编译器不喜欢演员表?t
D
class Program
{
public class B<T> where T : B<T> { }
public class D : B<D> { public void M() { Console.Out.WriteLine("D.M called."); } }
static void Main() { M(new D()); }
public static void M<T>(T t) where T : B<T>
{
// Works as expected: prints "D.M called."
var d = t as D;
if (d != null)
d.M();
// Compiler error: "Cannot cast expression of type 'T' to type 'D'."
// even though t really is a D!
if (t is D)
((D)t).M();
}
}
编辑:到处玩,我认为这是一个更清楚的例子。在这两种情况下t
都被限制为 aB
并且可能是 a D
。但是泛型的情况不会编译。在确定强制转换是否合法时,C# 是否只是忽略了通用约束?即使它确实忽略它,t
仍然可能是D
; 那么为什么这是编译时错误而不是运行时异常呢?
class Program2
{
public class B { }
public class D : B { public void M() { } }
static void Main()
{
M(new D());
}
public static void M(B t)
{
// Works fine!
if (t is D)
((D)t).M();
}
public static void M<T>(T t) where T : B
{
// Compile error!
if (t is D)
((D)t).M();
}
}