[英]What is the precedence when more than one method overload matches?
我正在嘗試了解C#中的OOP概念。
在以下示例代碼中:
ins1
更喜歡通用方法 ins2
, ins3
更喜歡非泛型方法 注意:當我注釋掉任何一個“MyTestMethod”方法時,程序仍然會繼續成功運行。 這段代碼不是來自制作的東西。 這只是我的訓練樣本。 所以,請不要介意命名約定和標准。
using System;
namespace ConsoleApplication1
{
class Program
{
public static void MyTestMethod(J input)
{
Console.WriteLine($"Program.MyTestMethod: {input.Val}");
}
public static void MyTestMethod<T>(T input) where T : J
{
Console.WriteLine($"Program.MyTestMethod<T>: {input.Val}");
}
static void Main(string[] args)
{
J2 ins1 = new J2(1);
MyTestMethod(ins1);
J ins2 = new J(2);
MyTestMethod(ins2);
J ins3 = new J2(3);
MyTestMethod(ins3);
Console.ReadKey();
}
}
internal class J
{
public int Val { get; set; }
public J(int i)
{
Console.WriteLine($"concrete base {i}");
Val = i;
}
}
internal class J2 : J
{
public J2(int i) : base(i * -1)
{
Console.WriteLine($"concrete {i}");
}
}
}
C#規范的第7.5.3.2節是這里的相關部分 - “更好的功能成員”。
結果更簡單地表現為:
using System;
class Test
{
static void Foo<T>(T item)
{
Console.WriteLine("Generic");
}
static void Foo(object x)
{
Console.WriteLine("Non-generic");
}
static void Main()
{
Foo(new object()); // Calls Foo(object)
Foo("test"); // Calls Foo<T>(T)
}
}
在兩個調用中,兩個重載都是適用的函數成員。 在選擇要調用的重載時,編譯器首先檢查從參數類型(或表達式)到參數類型的轉換是“更好”。
當參數的類型是object
, T
被推斷為object
,因此對於兩個候選者,轉換是object
到object
的身份轉換。 那時,涉及7.5.3.2的打破平局規則,第一個是:
如果M P是非通用方法並且M Q是通用方法,則M P優於M Q.
這就是為什么在這種情況下選擇非泛型重載的原因。
當參數是string
類型時, T
被推斷為string
,因此我們必須比較從string
到string
的轉換(對於泛型方法)到從string
到object
的轉換(對於非泛型方法)。 這里引入了C#規范的第7.5.3.3節,其中包括:
給定從表達式E轉換為類型T1的隱式轉換C1,以及從表達式E轉換為類型T2的隱式轉換C2,如果以下至少一個成立,則C1是比C2更好的轉換:
- E具有類型S,並且存在從S到T 1而不是從S到T 2的標識轉換
在這個上下文中,E是表達式“test”,S是類型string
,T 1是類型string
,T 2是類型object
,因此從字符串到字符串的轉換被認為更好 - 並且選擇了泛型方法。
為什么ins2,3更喜歡非泛型方法
因為在這兩種情況下, 變量的類型 (不是實例化類型)都是J
,這與具有簽名MyTestMethod(J input)
方法完全匹配。 因此,重載決策規則告訴它需要那個。
為什么ins1更喜歡通用方法
由於T
可以是方法MyTestMethod(T input) where T : J
J2
, MyTestMethod(T input) where T : J
,並且它可以強烈地將T
類型設置為J2
,再次,它是一個比基類J
更好的匹配,來自您的其他方法。 所以它將方法與類型參數匹配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.