C#中是否存在对应C++ std::variant(和类型/区分联合)的等价构造?
C# 中类似 C++ std::variant 的区分联合实现方案
原生实现方案(无第三方依赖)
C# 没有直接对应 std::variant 的原生语言构造,但可以通过自定义类型模拟,实现编译时类型安全的区分联合。以下是一个可存储 string 或 int 的示例:
public readonly struct StringOrInt { private readonly object? _value; public bool IsString { get; } public bool IsInt => !IsString; // 私有构造函数,仅允许内部创建实例 private StringOrInt(string value) { _value = value; IsString = true; } private StringOrInt(int value) { _value = value; IsString = false; } // 隐式转换,模拟std::variant的赋值行为 public static implicit operator StringOrInt(string value) => new(value); public static implicit operator StringOrInt(int value) => new(value); // 提供匹配方法,安全提取值 public T Match<T>(Func<string, T> stringHandler, Func<int, T> intHandler) { return IsString ? stringHandler((string)_value!) : intHandler((int)_value!); } }
使用示例:
StringOrInt v = "aaa"; // 存储string类型值 v = 5; // 切换为存储int类型值 // 通过Match方法处理不同类型 var output = v.Match( str => $"当前值是字符串:{str}", num => $"当前值是整数:{num}" ); Console.WriteLine(output);
该实现通过私有构造函数限制实例创建方式,确保只能赋值 string 或 int 类型,编译时会拦截非法赋值。
第三方库方案:OneOf
OneOf 是专门为C#实现的泛型区分联合库,行为和 std::variant 高度一致,且无需手动实现类型约束。
使用步骤:
- 通过NuGet安装OneOf库
- 定义并使用联合类型:
using OneOf; // 定义可存储string或int的联合类型 OneOf<string, int> v = "aaa"; // 存储string v = 5; // 切换为存储int // 用switch模式匹配处理不同类型 switch (v) { case string str: Console.WriteLine($"字符串值:{str}"); break; case int num: Console.WriteLine($"整数值:{num}"); break; } // 或使用Match方法 v.Match( str => Console.WriteLine($"字符串值:{str}"), num => Console.WriteLine($"整数值:{num}") );
OneOf 会在编译时强制类型约束,不允许赋值非指定类型的值,完全满足需求。
内容的提问来源于stack exchange,提问作者wohlstad
相关产品推荐
相关产品推荐

