c# - C# 中的重载解析、扩展方法和泛型

标签 c# generics extension-methods c#-5.0

我的 C# 源代码中有以下场景:

class A{}

class Dispatch<T>{}

static class DispatchExt
{
    public static void D<T>(this Dispatch<T> d, int a)
    {
         Console.WriteLine("Generic D chosen with a = " + a.ToString());
    }

    public static void D(this Dispatch<A> d, int a)
    {
         Console.WriteLine("D<A> chosen with a = " + a.ToString());
    }
}

class Program
{
     static void D<T>(Dispatch<T> d, int a)
     {
          d.D(a);
     }

     static void Main(string[] args)
     {
         int a = 5;
         var dispatch = new Dispatch<A>();
         dispatch.D(a);
         D(dispatch, a);
     }
}

当我运行这段代码时,输​​出是:

"D<A> 选择 a = 5"

“通用 D 选择 a = 5”

这个结果让我很吃惊,因为在这两种情况下我都期望“D<A> chosen with a = 5”。

我想知道在这种情况下一般的重载决议规则是什么,或者任何导致此输出的内容。此外,我想知道是否有一种方法可以在两种情况下都实现第一个输出。

最佳答案

扩展方法是在编译时仅使用从静态类型系统获取的信息进行解释的语法糖。

以你的第一个例子为例,你有这个:

dispatch.D(a);

dispatch类型为 Dispatch<A> ,存在扩展方法。所以编译器将其翻译成 DispatchExt.D(dispatch, a) (非通用版本)。

在你的第二个例子中,你有这个:

d.D(a);

d类型为 Dispatch<T> .所以这采用通用扩展方法 DispatchExt.D<T>(d, a) .

由于转换发生在编译时,因此不考虑实际的运行时类型。


这是顺便说一句。在其他情况下确定重载时使用相同的行为:仅考虑静态编译时类型:

A a = new A();
B b = new B();
A ba = b;

Test(a); // "a"
Test(b); // "b"
Test(ba); // "a"

使用以下定义:

public void Test(A a) { Console.WriteLine("a"); }
public void Test(B a) { Console.WriteLine("b"); }
public class A {}
public class B : A {}

关于c# - C# 中的重载解析、扩展方法和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33878866/

相关文章:

javascript - http.post 从 angularJS 到 c# Web api 的简单对象为 null 或所有属性均为 null

c# - 如何使用 C# 在 Unity 中解析复杂的 JSON 对象

Java 泛型的使用

java - 删除 ArrayList Java 中的重复元素

ios - Swift 协议(protocol)函数重载

ios - 委托(delegate)/协议(protocol)将数据从一个 View Controller 传递到另一个

asp.net - VB.Net 使用 System.Reflection 和 System.Type 初始化类以创建基于 session 的单例扩展方法

c# - 使用策略模式在 C# 上实现类似行为的多参数 C++ 模板

c# - 如何在 Awesomium 中禁用 Ctrl+p?

c# - 使用 ANTS Memory Profiler 在 ASP.NET 网站中发现内存泄漏?