簡體   English   中英

C#中的重載分辨率,擴展方法和通用性

[英]Overload resolution, extension methods and genericity in C#

我在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”

“選擇a = 5的通用D

這個結果讓我感到驚訝,因為在這兩種情況下,我都期待“ D<A> = A”選擇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 {}

我認為你的意思是這樣的 - 一種自稱的鏈式方法。 我做了一個數字總和的多次調用。

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;

        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM