代码有点奇怪,所以请耐心等待(请记住,这种情况确实出现在生产代码中)。
假设我有这个接口(interface)结构:
public interface IBase { }
public interface IChild : IBase { }
public interface IFoo<out T> where T : IBase { }
使用围绕接口(interface)构建的扩展方法类:
public static class FooExt
{
public static void DoSomething<TFoo>(this TFoo foo)
where TFoo : IFoo<IChild>
{
IFoo<IChild> bar = foo;
//foo.DoSomethingElse(); // Doesn't compile -- why not?
bar.DoSomethingElse(); // OK
DoSomethingElse(foo); // Also OK!
}
public static void DoSomethingElse(this IFoo<IBase> foo)
{
}
}
为什么 DoSomething
中注释掉的行不能编译?编译器非常乐意让我将 foo
分配给 bar
,它与通用约束具有相同的类型,并改为调用扩展方法。没有扩展方法语法调用扩展方法也是没问题的。
任何人都可以确认这是错误还是预期的行为?
谢谢!
仅供引用,这是编译错误(为便于阅读而删节的类型):
'TFoo' does not contain a definition for 'DoSomethingElse' and the best extension method overload 'DoSomethingElse(IFoo)' has some invalid arguments
最佳答案
引用 C# 规范:
7.6.5.2 Extension method invocations
In a method invocation (§7.5.5.1) of one of the forms
expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )
if the normal processing of the invocation finds no applicable methods, an attempt is made to process the construct as an extension method invocation. If expr or any of the args has compile-time type dynamic, extension methods will not apply.
The objective is to find the best type-name C, so that the corresponding static method invocation can take place:
C . identifier ( expr )
C . identifier ( expr , args )
C . identifier < typeargs > ( expr )
C . identifier < typeargs > ( expr , args )
An extension method Ci.Mj is eligible if:
· Ci is a non-generic, non-nested class
· The name of Mj is identifier
· Mj is accessible and applicable when applied to the arguments as a static method as shown above
· An implicit identity, reference or boxing conversion exists from expr to the type of the first parameter of Mj.
自 DoSomethingElse(foo)
编译但foo.DoSomethingElse()
没有,它似乎是扩展方法重载解析中的编译器错误:隐式引用转换存在于 foo
至 IFoo<IBase>
.
关于c# - 为什么这个通用扩展方法不能编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6034871/