簡體   English   中英

如何在 C# 中為內置類型設置別名?

[英]How to alias a built-in type in C#?

所以在 C++ 中,我習慣於能夠做到:

typedef int PeerId;

這使我可以使類型更具自文檔性,而且還允許我隨時使 PeerId 表示不同的類型,而無需更改所有代碼。 如果我願意,我什至可以將 PeerId 變成一個類。 這種可擴展性是我想要在 C# 中擁有的,但是我無法弄清楚如何在 C# 中為“int”創建別名。

我想我可以使用 using 語句,但它只在我相信的當前文件中具有范圍,因此不起作用(別名需要在多個文件之間可以訪問而無需重新定義)。 我也無法從內置類型派生類(但通常這是我對引用類型的別名所做的事情,例如列表或字典)。 我不確定我能做什么。 有任何想法嗎?

您需要使用完整的類型名稱,如下所示:

using DWORD = System.Int32;

摘要

這是簡短的回答:

  • Typedef實際上是編譯時代碼生成器使用的變量。
  • C#旨在避免添加代碼生成語言結構。

因此,typedef的概念不適合C#語言。

答案很長

在C ++中,它更有意義:C ++最初是作為一個預編譯器,它吐出C代碼,然后編譯。 這個“代碼生成器”開始仍然具有現代C ++特性的效果(即,模板本質上是用於在編譯時生成類和函數的圖靈完備語言)。 在這種情況下,typedef是有意義的,因為它是獲取編譯時類型工廠的“結果”或“返回”類型的“算法”的一種方法。

在這種奇怪的元語言中(Boost之外很少有人掌握),typedef實際上是一個變量。

您所描述的內容不那么復雜,但您仍在嘗試將typedef用作變量。 在這種情況下,它用作輸入變量。 因此,當其他代碼使用typedef時,它實際上並沒有直接使用該類型。 相反,它充當編譯時代碼生成器,基於typedef的輸入變量構建類和方法。 即使您忽略C ++模板並只看C typedef,效果也是一樣的。

C ++和生成編程

C ++被設計成一種多范式語言(OO和程序,但在Boost問世之前不起作用)。 有趣的是,模板已經發展出一種意想不到的范式:生成性編程。 (生成式編程在C ++之前就已存在,但C ++使它很受歡迎)。 生成程序實際上是元程序 - 在編譯時 - 生成所需的類和方法,這些類和方法又被編譯成可執行文件。

C#和生成編程

我們的工具正朝着同一個方向緩慢發展。 當然,反射發射可以用於“手動”生成編程,但是非常痛苦。 LINQ提供程序使用表達式樹的方式本質上非常具有生成性。 T4模板非常接近,但仍然不足。 如果它可以與某種類型的變量(例如typedef)結合使用,那么希望成為C#vNext一部分的“編譯器即服務”似乎最有希望。

這個難題的一部分仍然缺失 :生成程序需要某種自動觸發機制(在C ++中,這由隱式模板實例化處理)。

但是,在C#語言中使用任何類型的“代碼生成器”(如C ++模板)可能明顯不是 C#的目標(可能為了可理解性;很少有C ++程序員理解C ++模板)。 這可能是T4而不是C#所滿足的利基。

結論(重復摘要)

所有這些都是這樣說的:

  • Typedef是代碼生成器使用的變量。
  • C#旨在避免添加代碼生成語言結構。

因此,typedef的概念不適合C#語言。

你可以(ab)使用隱式轉換:

struct PeerId
{
    private int peer;

    public static implicit operator PeerId(int i)
    {
        return new PeerId {peer=i};
    }

    public static implicit operator int(PeerId p)
    {
        return p.peer;
    }
}

這與int占用相同的空間,您可以這樣做:

PeerId p = 3;
int i = p;

但我同意你可能不需要這個。

我有時也覺得我需要(整數)typedef用於與OP類似的目的。

如果你不介意演員是明確的(我實際上希望他們),你可以這樣做:

enum PeerId : int {};

也適用於byte, sbyte, short, ushort, uint, long,ulong (顯然)。

不完全是enum的預期用法,但它確實有效。

為了更改名稱而重新定義基本類型是C ++認為並且不適合更純粹的面向對象的C#。 每當你想要將一種概念從一種語言轉換為另一種語言時,你必須停下來思考它是否有意義,並嘗試保持原生於平台。

通過定義自己的值類型,可以滿足能夠輕松更改基礎類型的要求。 與隱式轉換運算符和算術運算符相結合,您可以定義非常強大的類型。 如果您擔心在簡單類型之上添加圖層的性能,請不要。 99%的可能性它不會,1%的可能性是,如果確實如此,它將不會是性能優化的“低懸的果實”。

從 C# 10 開始,您可以使用:

global using PeerId = System.Int32;

它適用於所有文件。

它應該出現在所有沒有全局修飾符的 using 指令之前。

請參閱using 指令

暫無
暫無

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

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