gpt4 book ai didi

C# 方法重载解析不选择具体的泛型覆盖

转载 作者:行者123 更新时间:2023-11-30 18:13:24 24 4
gpt4 key购买 nike

这个完整的 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com