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

本文关键字:扩展 方法 泛型 重载 | 更新日期: 2023-09-27 18:23:56

我的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);
     }
}

当我运行此代码时,输出为:

"用a=5选择D<A>"

"使用a=5选择的通用D"

这个结果让我很惊讶,因为在这两种情况下,我都期望"D<A>被选为a=5"。

我想知道在这种情况下,一般的过载解决规则是什么,或者任何导致这种输出的规则。此外,我想知道是否有办法在这两种情况下都能获得第一个输出。

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

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

举你的第一个例子,你有这样的:

dispatch.D(a);

dispatch属于Dispatch<A>类型,存在扩展方法。因此编译器将其转换为DispatchExt.D(dispatch, a)(非通用版本)。

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

d.D(a);

CCD_ 7属于CCD_。因此,这采用了通用的扩展方法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 {}

我想你的意思是这样的——一个调用自己的链接方法。我打了多次电话求和。

using System; 
namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var magic = new Magic();
            var sum = magic.MagicAdd(2).MagicAdd(20).MagicAdd(50).MagicAdd(20).Result;
            Console.WriteLine(sum);
            Console.ReadKey();
        }
    }
    public class Magic
    {
        public int Result { get; set; }
        //method chaining
        public Magic MagicAdd(int num)
        {
            this.Sum(num);
            return this;
        }
        public int Sum(int x)
        {
            this.Result = this.Result + x;
            return this.Result;
        }
    }
}