news 2026/4/16 10:48:33

c++ 17的std::variant对标c#的哪个类型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c++ 17的std::variant对标c#的哪个类型

C# 的System.Objectdynamic和 C# 7.0+ 引入的System.ValueTuple以及System.OneOf等都可以实现类似功能,但最接近 C++std::variant语义的是:

1. 官方方案:System.Object和模式匹配(最接近)

基础用法

csharp

// 类似 std::variant<int, string, bool> object variant = 42; // 可以是任何类型 // 类型检查与提取(C# 7.0+ 模式匹配) switch (variant) { case int i: Console.WriteLine($"Integer: {i}"); break; case string s: Console.WriteLine($"String: {s}"); break; case bool b: Console.WriteLine($"Bool: {b}"); break; default: Console.WriteLine($"Unknown type: {variant.GetType()}"); break; }

现代模式匹配(C# 8.0+)

csharp

object value = "Hello"; var result = value switch { int i => $"Integer {i}", string s => $"String length: {s.Length}", bool b => $"Boolean: {b}", _ => "Unknown type" };

2. 官方增强:可空引用类型 + 模式匹配

csharp

3. 第三方库:OneOf(推荐,最接近 std::variant)

NuGet 包:OneOf

基本用法

csharp

// 表示可能为 string 或 int 的类型 sealed class StringOrInt { private readonly object _value; private StringOrInt(object value) => _value = value; public static StringOrInt FromString(string s) => new(s); public static StringOrInt FromInt(int i) => new(i); public T Match<T>(Func<string, T> stringCase, Func<int, T> intCase) { return _value switch { string s => stringCase(s), int i => intCase(i), _ => throw new InvalidOperationException() }; } } // 使用 var variant = StringOrInt.FromString("test"); var result = variant.Match( s => $"String: {s}", i => $"Int: {i}" );

更复杂的示例

csharp

// 错误处理场景(类似 std::variant<Success, Error>) OneOf<Success, NotFound, ValidationError> result = ProcessRequest(); var response = result.Match( success => Ok(success.Data), notFound => NotFound(notFound.Message), validationError => BadRequest(validationError.Errors) ); // 模式匹配风格(C# 8.0+) if (result.TryPickT0(out Success success, out var remaining)) { // 成功处理 } else if (remaining.TryPickT0(out NotFound notFound, out var remaining2)) { // 未找到处理 } else if (remaining2.TryPickT0(out ValidationError error, out _)) { // 验证错误处理 }

4. 值类型变体:ValueTuple+ 枚举

csharp

// 使用 ValueTuple 实现轻量级变体 enum VariantType { Int, String, Bool } (VariantType Type, object Value) variant = (VariantType.String, "Hello"); switch (variant.Type) { case VariantType.Int: int i = (int)variant.Value; break; case VariantType.String: string s = (string)variant.Value; break; case VariantType.Bool: bool b = (bool)variant.Value; break; }

5. 泛型联合类型(自定义实现)

csharp

// 类似 C++ std::variant 的强类型实现 public readonly struct Variant<T1, T2> { private readonly T1 _value1; private readonly T2 _value2; private readonly byte _index; private Variant(T1 value) => (_value1, _index) = (value, 1); private Variant(T2 value) => (_value2, _index) = (value, 2); public static implicit operator Variant<T1, T2>(T1 value) => new(value); public static implicit operator Variant<T1, T2>(T2 value) => new(value); public TResult Match<TResult>(Func<T1, TResult> f1, Func<T2, TResult> f2) { return _index switch { 1 => f1(_value1), 2 => f2(_value2), _ => throw new InvalidOperationException() }; } } // 使用 Variant<int, string> variant = "Hello"; int length = variant.Match( i => i * 2, s => s.Length );

6.dynamic类型(灵活性最高,但无类型安全)

csharp

// 类似 std::variant,但无编译时类型检查 dynamic variant = 10; // 现在是 int variant = "Hello"; // 现在是 string variant = new List<int>(); // 现在是 List<int> // 运行时类型检查 if (variant is string str) { Console.WriteLine(str.ToUpper()); }

与 C++std::variant的对比

特性C++std::variantC# 最接近方案
类型安全✅ 编译时检查OneOf: ✅
object: ❌ 运行时检查
值语义✅ 栈分配struct/ValueTuple: ✅
object: ❌ 堆分配
访问方式std::visitgetMatch/Switch、模式匹配
空状态std::monostateNullable<T>Optional模式
性能✅ 高效OneOf/struct: ✅
object: ⚠️ 有装箱开销
异常处理std::bad_variant_accessInvalidCastException

推荐方案选择

场景建议:

1.简单临时使用object+ 模式匹配

object data = GetData(); if (data is string s) { ... }

2.API 设计/错误处理OneOf(NuGet)

OneOf<User, NotFound, ValidationError> GetUser(int id);

3.性能敏感场景自定义struct变体

readonly struct ResultOrError<T> { ... }

4.动态/脚本场景dynamic

dynamic result = Process(); Console.WriteLine(result.Value);

5.现代 C#(8.0+)模式匹配 + 记录类型

record Success(string Data); record Error(string Message); object result = new Success("Done"); var message = result switch { Success s => s.Data, Error e => $"Error: {e.Message}", _ => "Unknown" };

实际应用示例

csharp

// Web API 响应类型 public class ApiResponse { // 使用 OneOf 表示成功、错误、未找到 public OneOf<SuccessResponse, ErrorResponse, NotFoundResponse> Result { get; } public ApiResponse(SuccessResponse success) => Result = success; public ApiResponse(ErrorResponse error) => Result = error; public ApiResponse(NotFoundResponse notFound) => Result = notFound; public IActionResult ToActionResult() { return Result.Match<IActionResult>( success => Ok(success), error => BadRequest(error), notFound => NotFound(notFound) ); } } // 解析器结果 public OneOf<int, double, string, ParseError> ParseExpression(string input) { if (string.IsNullOrEmpty(input)) return new ParseError("Empty input"); if (int.TryParse(input, out int intValue)) return intValue; if (double.TryParse(input, out double doubleValue)) return doubleValue; return input; // 返回原始字符串 }

总结

C# 没有内置的完全等同于std::variant的类型,但通过以下方式可以实现相似功能:

  1. OneOf- 最接近std::variant的语义和用法

  2. object+ 模式匹配- 简单通用,但缺乏类型安全

  3. 自定义值类型- 性能最佳,适合特定场景

  4. 记录类型 + 模式匹配- C# 9.0+ 现代函数式风格

推荐:对于新项目,如果需要类似std::variant的功能,首选OneOf。它提供了类型安全、良好的API和性能,最符合C++开发者的直觉。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 9:24:58

在NEAR Protocol中获取用户账户的完整指南

近年来,随着区块链技术的发展,NEAR Protocol作为一个高效的智能合约平台,吸引了越来越多的开发者和用户。今天,我们将探讨如何在NEAR Protocol中获取用户账户列表,这对开发者来说是一个常见的需求,尤其是在进行用户数据分析或开发用户相关的应用时。 问题背景 在NEAR P…

作者头像 李华
网站建设 2026/4/16 10:18:03

格雷希尔:G15F-KFYK-FD39 定制款快速密封连接器,适配自动化产线,赋能电驱动通讯接口的自动化密封测试

某新能源设备商联系到我们&#xff0c;为其电驱动上的通讯接口采购一批快速密封连接器用于气密性测试&#xff0c;该生产线为自动化产线&#xff0c;对连接器的适配性、稳走性、耐用性均提出了极高要求。格雷希尔定制款 G15F-KFYK-FD39 自动化连接器格雷希尔定制款 G15F-KFYK-F…

作者头像 李华
网站建设 2026/4/16 10:16:42

2025年终总结 - 微分几何助力突破具身智能发展的瓶颈

今天是 2025 年 12 月 31 日&#xff0c;又到了一年一度回顾与思考的时刻。回望 2025 年&#xff0c;人工智能正在以前所未有的速度重塑人类社会结构&#xff0c;而具身智能&#xff08;Embodied Intelligence&#xff09;正逐渐成为这一轮技术浪潮中的核心焦点。所谓具身智能&…

作者头像 李华
网站建设 2026/4/16 10:18:35

Nordic方案——无线射频模组AS01-ML01SC

Nordic Semiconductor在无线性能和精密度方面拥有领先业界的表现&#xff0c;即使是对成本极为敏感的消费类产品&#xff0c;也能运用该公司的超低功耗 (ULP) 无线芯片。Nordic Semiconductor的芯片广泛用于无线PC外设、游戏控制器、体育和健身传感器、玩具、先进的多媒体控制器…

作者头像 李华
网站建设 2026/4/14 20:08:18

力扣96 不同的二叉搜索树 java实现

96.不同的二叉搜索树给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。示例 1&#xff1a;输入&#xff1a;n 3 输出&#xff1a;5示例 2&#xff1a;输入&#xff1a;n 1 输出…

作者头像 李华
网站建设 2026/4/15 18:30:39

全网最全专科生必用TOP8 AI论文平台测评

全网最全专科生必用TOP8 AI论文平台测评 2026年专科生论文写作工具测评&#xff1a;为何需要一份权威榜单&#xff1f; 随着AI技术在学术领域的广泛应用&#xff0c;越来越多的专科生开始借助AI工具提升论文写作效率。然而&#xff0c;面对市场上琳琅满目的论文平台&#xff0c…

作者头像 李华