這個做法提出如果你有泛型方法,那就不要再創建針對基底類別或介面的多載方法, 可以猜猜下面這段程式碼的輸出為何。
void Main()
{
MyDerived d = new MyDerived();
Console.WriteLine("Calling Program.WriteMessage");
WriteMessage(d);
Console.WriteLine();
Console.WriteLine("Calling through IMessageWriter interface");
WriteMessage((IMessageWriter)d);
Console.WriteLine();
Console.WriteLine("Cast to base object");
WriteMessage((MyBase)d);
Console.WriteLine();
Console.WriteLine("Another Type test:");
AnotherType anObject = new AnotherType();
WriteMessage(anObject);
Console.WriteLine();
Console.WriteLine("Cast to IMessageWriter:");
WriteMessage((IMessageWriter)anObject);
}
public class MyBase{}
public interface IMessageWriter
{
void WriteMessage();
}
public class MyDerived : MyBase, IMessageWriter
{
void IMessageWriter.WriteMessage() => Console.WriteLine("Inside MyDerived.WriteMessage");
}
public class AnotherType : IMessageWriter
{
public void WriteMessage() => Console.WriteLine("Inside AnotherType.WriteMessage");
}
static void WriteMessage(MyBase b)
{
Console.WriteLine("Inside WriteMessage(MyBase)");
}
static void WriteMessage<T>(T obj)
{
Console.Write("Inside WriteMessage<T>(T): ");
Console.WriteLine(obj.ToString());
}
static void WriteMessage(IMessageWriter obj)
{
Console.Write("Inside WriteMessage(IMessageWriter): ");
obj.WriteMessage();
}
從第一個方法呼叫就能看出這個特性,MyDerived
實際上是使用泛型的多載版本,而不是使用 MyBase
的多載版本。
Calling Program.WriteMessage
Inside WriteMessage<T>(T): UserQuery+MyDerived
Calling through IMessageWriter interface
Inside WriteMessage(IMessageWriter): Inside MyDerived.WriteMessage
Cast to base object
Inside WriteMessage(MyBase)
Another Type test:
Inside WriteMessage<T>(T): UserQuery+AnotherType
Cast to IMessageWriter:
Inside WriteMessage(IMessageWriter): Inside AnotherType.WriteMessage
為什麼是優先使用WriteMessage<T>(T obj)
而不是 WriteMessage(MyBase b)
?
是因為編譯器可以直接將 T 轉換成 MyDerived
這樣就變成完全符合需求的方法,然而 WriteMessage(MyBase b)
使用起來還要
透過隱含轉換把 MyDerived
轉成 MyBase
,也就是為什麼會優先使用泛型版本。
Summary
這個做法比較簡單,就是在講有泛型的方法時最好不要再創建針對基底類別或介面的多載方法,如果真的需要的話就要針對所有基底類型與它的 所有衍生類型都建立多載版本。