簡體   English   中英

C#中的多態,重載和泛型

[英]Polymorphism, overloads and generics in C#

class Poly
    {
    public static void WriteVal(int i) { System.Console.Write("{0}\n", i); }
    public static void WriteVal(string s) { System.Console.Write("{0}\n", s); }
    }

class GenWriter<T>
    {
        public static void Write(T x) { Poly.WriteVal(x); }
    }

為什么無辜(對於C ++程序員)方法寫入在C#中是不可接受的?

您可以看到編譯器實例化之前嘗試將參數類型T與具體重載匹配:

當然。 目的不是使用上面的靜態方法,目的是創建一個具有多態行為的包裝器。 注意:我使用的是VS 2010。

請注意,所有需要的信息都可在編譯時獲得。 再一次:問題是在模板實例化之前執行驗證。

討論后增加:

好吧,可能我沒有正確地強調這一點。 問題不僅在於泛型和模板之間的區別,還在於解決以下問題:給定一組解決不同類型的重載,我想生成一組包裝類,為這些類型提供虛方法(多態)。 運行時虛擬方法的解析價格很小,並沒有達到性能。 這是C ++模板很方便的地方。 顯然, 動態的運行時類型解析的開銷是完全不同的。 因此,問題是,是否可以在不復制代碼的情況下將現有的重載轉換為多態,並且不會犧牲性能損失(例如,我不確定動態與“switch”相比,除了更好的語法之外的“switch”)。

到目前為止我見過的解決方案之一是生成/發出代碼(sic!),即不是自動剪切和粘貼。

因此,我們只需手動執行或僅重新創建宏/模板處理器,而不是C ++模板處理。

還有什么更好的?

簡短回答:

C#泛型不是C ++模板; 盡管它們的語法相似但卻完全不同。 模板是在編譯時構建的,每次實例化一次,並且模板化代碼必須僅對實際提供的模板參數是正確的。 模板在每次實例化時執行重載解析和類型分析等任務; 它們基本上是源代碼文本上的智能“搜索和替換”機制。

C#泛型是真正的通用類型; 它們必須對任何可能的類型參數都是正確的。 分析通用代碼一次 ,重載分辨率完成一次 ,依此類推。

答案很長:這是重復的

C#和Java中的泛型與C ++中的模板有什么區別?

請查看詳細的長答案。

另見我關於這個主題的文章:

http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx

為什么你不能簡單地寫:

public static void Write<T>(T x) { System.Console.Write("{0}\n", x); }

C ++和C#泛型不同( http://msdn.microsoft.com/en-us/library/c6cyy67b(v=VS.80).aspx ,在您最喜歡的搜索網站上搜索“c#c ++泛型差異”)

簡短:C#編譯器必須通過查看類本身來創建具有所有類型匹配的完整GenWriter<T>類。 所以它不知道T是否只是int / string或任何其他類型。

C ++編譯器通過查看通用GenWriter<int>和聲明GenWriter<T>實例化來創建實際類,然后為該特定實例創建類。

如果有人要調用GenWriter(5.0) ,這將被推斷為GenWriter<double>(5.0) ,並且Write(T x)內的方法調用將變為:

public static void Write(double x) { Poly.WriteVal(x); }

WriteVal沒有超載,需要加倍。 編譯器通知您沒有WriteVal有效重載。

C#泛型和C ++模板並不完全等效。

你不能在C#中這樣做,因為編譯器不知道編譯時x的類型是什么。

如果不了解T的實際類型,編譯器會擔心您可能打算執行自定義轉換。 最簡單的解決方案是使用as運算符,因為它無法執行自定義轉換,因此無法實現。

更普遍的解決方案是首先投射到對象。 這是有幫助的,因為拳擊拆箱問題:

return (int)(object) x;

請記住,C#Generics不像C ++模板。 C ++模板是分別為每種類型編譯的代碼片段。 雖然C#泛型是以匯編方式編譯的。

暫無
暫無

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

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