ค้นหาเว็บไซต์

ประเภทกำหนดเองใน 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 ได้ แต่ไม่แนะนำเนื่องจากอาจเกิดข้อผิดพลาดในเวลารันไทม์

บทความที่เกี่ยวข้อง