C# 中的自訂型別(類似 TypeScript)
在 TypeScript 中,我可以這樣定義一個類型,使其可以是字串或字串陣列
type MyStringType = string | string[]
我可以在 C# 做類似的事情嗎?
答案#1
C# 沒有聯合類型的功能。有一些提案,但我不認為它們會在短期內被實施。
話雖如此,你可以實現你自己的自訂包裝類型,並在使用之前將輸入轉換為該類型。
struct Union<T1, T2>
{
public T1 Left { get; }
public T2 Right { get; }
public bool IsLeft => !IsRight;
public bool IsRight { get; }
public Union(T1 left) => (Left, Right, IsRight) = (left, default, false);
public Union(T2 right) => (Left, Right, IsRight) = (default, right, true);
public static implicit operator Union<T1, T2>(T1 left) => new Union<T1, T2>(left);
public static implicit operator Union<T1, T2>(T2 right) => new Union<T1, T2>(right);
}
由於隱式轉換,你可以在需要聯合類型的地方使用任何變體的值。因此以下兩者都有效:
void Foo(Union<string, string[]> val){}
Foo("str")
Foo(new string[] {"str1", "str2"});
請注意,這不是生產等級的實作。你可能會想要覆寫 Equals,如果有人在 IsLeft 為 false 時存取 Left,或反之,則可能丟出 InvalidOperationException。
一個實際支援語言的實作會有較少的開銷(可能重複使用一個大小為 max(sizeof(T1), sizeof(T2)) 的欄位),但唉,這確實可行™,且具有強型別。
答案#2
不,你不可以。C# 是一種強類型語言,目前(尚未)允許宣告一個變數為多種類型。
有使用 dynamic 關鍵字的選項:https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic
該類型是靜態類型,但動態類型的對象會繞過靜態類型檢查。在大多數情況下,它的功能就像具有 object 類型一樣。在編譯時,被標記為 dynamic 的元素被假定支持任何操作。因此,您不必擔心該對象是從 COM API、動態語言如 IronPython、HTML 文檔對象模型 (DOM)、反射,還是程式的其他地方獲取值。然而,如果代碼無效
實際上它可以作為 TypeScript 中的 any 類型使用,但由於可能的運行時錯誤,不建議這麼做。
