ประเภทกำหนดเองใน C# (คล้ายกับ TypeScript)
ใน TypeScript ฉันสามารถกำหนดชนิดให้เป็นได้ทั้งสตริงหรืออาร์เรย์ของสตริงแบบนี้
type MyStringType = string | string[]
ฉันสามารถทำสิ่งที่คล้ายกันใน C# ได้ไหม?
คำตอบ #1
C# ไม่มีฟีเจอร์สำหรับ union types มีข้อเสนออยู่ไม่กี่อย่าง แต่ฉันไม่คิดว่าพวกมันกำลังถูกวางแผนในเร็วๆ นี้
ดังที่ได้กล่าวมาแล้ว คุณสามารถสร้างประเภทตัวห่อหุ้มแบบกำหนดเองของคุณเองและให้ค่าป้อนข้อมูลถูกแปลงเป็นประเภทนั้นก่อนที่จะนำไปใช้ได้
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 อาจจะโยน InvalidOperationException หากมีคนเข้าถึง Left เมื่อ IsLeft เป็น false และในทางกลับกัน
การใช้งานที่สนับสนุนโดยภาษาจริงจะมีค่าใช้จ่ายในการจัดการน้อยกว่า (อาจใช้ซ้ำเพียงฟิลด์เดียวขนาด max(sizeof(T1), sizeof(T2)))) แต่ก็เป็นเช่นนี้ Works™ และมีการพิมพ์ชนิดแบบเข้มงวด
คำตอบ #2
ไม่ คุณทำไม่ได้ C# เป็นภาษาที่มีประเภทข้อมูลเข้มงวดซึ่งยังไม่อนุญาตให้ประกาศตัวแปรให้มีหลายประเภทได้
มีตัวเลือกในการใช้คีย์เวิร์ด dynamic: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic
ประเภทเป็นประเภทคงที่ แต่สิ่งที่เป็นวัตถุประเภท dynamic จะข้ามการตรวจสอบประเภทคงที่ ในกรณีส่วนใหญ่ มันทำงานเหมือนกับว่ามีประเภท object ในเวลาคอมไพล์ องค์ประกอบที่ระบุประเภทเป็น dynamic จะถือว่ารองรับการดำเนินการใด ๆ ดังนั้นคุณไม่จำเป็นต้องกังวลว่าวัตถุรับค่าของมันมาจาก COM API, จากภาษาที่มีความยืดหยุ่นเช่น IronPython, จาก HTML Document Object Model (DOM), จาก reflection หรือจากที่อื่นในโปรแกรม อย่างไรก็ตาม หากโค้ดไม่ถูกต้อง
ในเชิงปฏิบัติ มันสามารถถูกใช้เป็นประเภท any ใน TypeScript ได้ แต่ไม่แนะนำเนื่องจากอาจเกิดข้อผิดพลาดในเวลารันไทม์
