You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#能否实现类似TypeScript中string|string[]的联合自定义类型?

当然可以!C#里虽然没有TypeScript那种直接写string | string[]的联合类型语法,但有好几种方式能实现类似的效果,我给你分享几个常用的方案:

方案1:用结构体+隐式转换模拟

这种方式可以让你像使用原生类型一样直接给自定义类型赋值string或者string[],非常接近TypeScript的使用体验:

public struct MyStringType
{
    private readonly object _value;

    // 私有构造函数,确保只能通过隐式转换创建实例
    private MyStringType(object value)
    {
        _value = value ?? throw new ArgumentNullException(nameof(value));
    }

    // 隐式转换:允许直接把string赋值给MyStringType
    public static implicit operator MyStringType(string value)
    {
        return new MyStringType(value);
    }

    // 隐式转换:允许直接把string[]赋值给MyStringType
    public static implicit operator MyStringType(string[] value)
    {
        return new MyStringType(value);
    }

    // 安全获取string类型的值
    public bool TryGetString(out string result)
    {
        result = _value as string;
        return result != null;
    }

    // 安全获取string[]类型的值
    public bool TryGetStringArray(out string[] result)
    {
        result = _value as string[];
        return result != null;
    }

    // 通用取值方法(需要指定类型)
    public T? GetValue<T>() where T : class
    {
        return _value as T;
    }
}

使用示例

// 直接赋值,和TypeScript一样方便
MyStringType singleString = "Hello World";
MyStringType stringArray = new[] { "Apple", "Banana", "Cherry" };

// 使用时通过类型检查获取实际值
if (singleString.TryGetString(out var str))
{
    Console.WriteLine($"Single string content: {str}");
}

if (stringArray.TryGetStringArray(out var arr))
{
    Console.WriteLine($"Array has {arr.Length} elements");
}

方案2:用抽象类实现受约束的“判别联合”

如果想要更严格的类型安全(避免不小心存入其他类型的值),可以用抽象类+密封子类的方式实现判别联合,这也是C#里模拟联合类型的推荐方式:

public abstract class MyStringType
{
    // 私有构造函数,确保只有内部子类能继承
    private MyStringType() { }

    // 表示单个字符串的子类
    public sealed class SingleString : MyStringType
    {
        public string Value { get; }

        public SingleString(string value)
        {
            Value = value ?? throw new ArgumentNullException(nameof(value));
        }
    }

    // 表示字符串数组的子类
    public sealed class StringArray : MyStringType
    {
        public string[] Value { get; }

        public StringArray(string[] value)
        {
            Value = value ?? throw new ArgumentNullException(nameof(value));
        }
    }

    // 提供便捷的创建方法
    public static MyStringType FromString(string value) => new SingleString(value);
    public static MyStringType FromStringArray(string[] value) => new StringArray(value);
}

使用示例

MyStringType myValue = MyStringType.FromString("Test");
MyStringType myArray = MyStringType.FromStringArray(new[] { "X", "Y", "Z" });

// 使用模式匹配处理不同类型,编译时就能确保覆盖所有情况
switch (myValue)
{
    case MyStringType.SingleString single:
        Console.WriteLine($"Got single string: {single.Value}");
        break;
    case MyStringType.StringArray array:
        Console.WriteLine($"Got array with {array.Value.Length} items");
        break;
}

方案3:使用第三方库简化实现

如果不想自己写这些模板代码,可以用成熟的第三方库,比如OneOf(可以通过NuGet安装),它专门用来处理C#里的联合类型,语法非常接近TypeScript:

using OneOf;

// 直接定义联合类型,和TypeScript的写法几乎一致
using MyStringType = OneOf<string, string[]>;

// 使用示例
MyStringType value = "Hello";
value = new[] { "A", "B", "C" };

// 用Switch方法快速处理不同类型
value.Switch(
    str => Console.WriteLine($"String content: {str}"),
    arr => Console.WriteLine($"Array length: {arr.Length}")
);

总结

  • 如果追求最接近TypeScript的使用体验,选方案1;
  • 如果需要严格的类型安全,避免非法值,选方案2;
  • 如果想少写模板代码,选方案3的第三方库。

内容的提问来源于stack exchange,提问作者ShanieMoonlight

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:12:47