- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这个完整的 C# 程序说明了这个问题:
public abstract class Executor<T>
{
public abstract void Execute(T item);
}
class StringExecutor : Executor<string>
{
public void Execute(object item)
{
// why does this method call back into itself instead of binding
// to the more specific "string" overload.
this.Execute((string)item);
}
public override void Execute(string item) { }
}
class Program
{
static void Main(string[] args)
{
object item = "value";
new StringExecutor()
// stack overflow
.Execute(item);
}
}
我遇到了一个 StackOverlowException,我追溯到这个调用模式,在这个模式中我试图将调用转发到更具体的重载。令我惊讶的是,调用并没有选择更具体的重载,而是回调自身。它显然与通用的基类型有关,但我不明白为什么它不选择 Execute(string) 重载。
有没有人对此有任何见解?
上面的代码被简化以显示模式,实际结构有点复杂,但问题是一样的。
最佳答案
看起来 C# 规范 5.0、7.5.3 重载解决方案中提到了这一点:
Overload resolution selects the function member to invoke in the following distinct contexts within C#:
- Invocation of a method named in an invocation-expression (§7.6.5.1).
- Invocation of an instance constructor named in an object-creation-expression (§7.6.10.1).
- Invocation of an indexer accessor through an element-access (§7.6.6).
- Invocation of a predefined or user-defined operator referenced in an expression (§7.3.3 and §7.3.4).
Each of these contexts defines the set of candidate function members and the list of arguments in its own unique way, as described in detail in the sections listed above. For example, the set of candidates for a method invocation does not include methods marked override (§7.4), and methods in a base class are not candidates if any method in a derived class is applicable (§7.6.5.1).
当我们查看 7.4 时:
A member lookup of a name N with K type parameters in a type T is processed as follows:
• First, a set of accessible members named N is determined:
If T is a type parameter, then the set is the union of the sets of
accessible members named N in each of the types specified as a primary constraint or secondary constraint (§10.1.5) for T, along with the set of accessible members named N in object.Otherwise, the set consists of all accessible (§3.5) members named N in T, including inherited members and the accessible membersnamed N in object. If T is a constructed type, the set of members is obtained by substituting type arguments as described in §10.3.2. Members that include an override modifier are excluded from the set.
如果您删除 override
,编译器会在您转换项目时选择 Execute(string)
重载。
关于C# 方法重载解析不选择具体的泛型覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52549449/
我是一名优秀的程序员,十分优秀!