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++开发者的直觉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1125873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国抽对接规则

1、国抽可以同步下来 待填报之前的样品信息&#xff08;包括正在接样状态&#xff09;。 2、国抽可以同步下来 待填报且已维护基础表的项目信息&#xff08;基础表维护按照报送分类B及细类维护&#xff0c;或特殊样品的项目维护&#xff09;。

神经网络架构搜索在模型优化中的应用

神经网络架构搜索在模型优化中的应用 关键词:神经网络架构搜索、模型优化、自动化机器学习、深度学习、搜索算法、架构表示 摘要:本文深入探讨了神经网络架构搜索(NAS)在模型优化中的应用。首先介绍了NAS的背景,包括其目的、预期读者和文档结构等。接着阐述了NAS的核心概念…

优雅的汉堡菜单动画实现

在前端开发中,如何创建一个既美观又实用的汉堡菜单是很多设计师和开发者常常面对的问题。今天我们将探讨如何实现一个既简单又优雅的汉堡菜单动画,确保动画过程中菜单的三条线条能准确地形成“X”形。 问题背景 通常,当我们点击汉堡菜单按钮时,希望上、中、下三条线条能够…

Matlab CEEMDAN-CPO-VMD-Transformer多变量时序预测

目录 1、代码简介 2、代码运行结果展示 3、代码获取 1、代码简介 [独家首发原创](双分解)CEEMDAN-CPO-VMD-Transformer多变量时序预测 (多输入单输出) Matlab代码 CEEMDAN分解&#xff0c;计算样本熵&#xff0c;根据样本熵进行kmeans聚类&#xff0c;调用CPO-VMD对高频分…

狂揽23.5k Star!我用这个开源神器,拖拉拽3分钟就撸好一个AI Agent

AI 时代&#xff0c;谁都想构建一个自己的 AI 应用&#xff0c;比如一个能读取 PDF 内容并回答问题的机器人&#xff0c;或者一个自动生成营销文案的工具。但一想到要跟 LangChain、API 接口和复杂的 Python 代码打交道&#xff0c;我就头皮发麻。难道不懂代码&#xff0c;就注…

再见 Typeform!我用这个开源平替,3分钟搞定无限问卷和数据私有化

无论是做用户满意度调研&#xff0c;还是收集活动报名信息&#xff0c;我都离不开在线问卷。Typeform、问卷星这类工具虽然好用&#xff0c;但它们的商业版价格不菲&#xff0c;而且免费版总是在“回复数量”或“问题数量”上处处受限。更重要的是&#xff0c;所有宝贵的用户数…

基于IWOA-CNN-BiLSTM-Attention多变量时序预测 Matlab代码

目录 1、代码简介 2、代码运行结果展示 3、代码获取 1、代码简介 [独家原创]基于IWOA-CNN-BiLSTM-Attention多变量时序预测 Matlab代码 改进点&#xff1a;三个(附赠参考文献)--------【如需优化算法(IWOA)测试函数&#xff0c;额外加20】 1、准反向学习---来初始化种群 …

【毕业设计】SpringBoot+Vue+MySQL 企业客户管理系统平台源码+数据库+论文+部署文档

摘要 随着信息技术的快速发展&#xff0c;企业客户管理系统的需求日益增长。传统的手工记录和纸质化管理方式效率低下&#xff0c;难以满足现代企业对客户信息的高效管理和数据分析需求。企业客户管理系统通过信息化手段整合客户数据&#xff0c;优化业务流程&#xff0c;提升客…

基于贝叶斯算法优化BP神经网络(BO-BP/Bayes-BP)的数据单变量时序预测 Matlab

目录 1、代码简介 2、代码运行结果展示 3、代码获取 1、代码简介 基于贝叶斯算法优化BP神经网络(BO-BP/Bayes-BP)的数据单变量时序预测 Matlab代码 程序已经调试好&#xff0c;无需更改代码替换数据集即可运行&#xff01;&#xff01;&#xff01;数据为电力数据&#xf…

狂揽77k Star!我用3分钟,给本地服务安上了公网域名

我经常需要在外面访问家里的 NAS&#xff0c;或者给客户演示我电脑上一个还没上线的项目。每次都被内网穿透搞得头疼不已&#xff0c;不是要研究复杂的路由器设置&#xff0c;就是要忍受那些又慢又不稳定的免费服务。传统内网穿透&#xff0c;太折腾了想靠自己搞定内网穿透&…

RESTful API 设计的最佳实践

在设计RESTful API时,我们经常会遇到如何优化数据获取的问题,特别是在处理相关实体数据时。让我们通过一个实际的例子来探讨如何实现RESTful API的最佳实践。 背景 假设我们有一个博客系统,API的基本结构如下: GET /api/v1/posts/1/ {"id": 1,"title&quo…

Rust与Python的HTTP请求对比

在编程世界中,HTTP请求是开发者常用的工具之一。不论是获取数据、提交表单还是与API交互,HTTP请求都是不可或缺的一部分。今天,我们将通过一个实际的例子来对比Python的requests库和Rust的reqwest库在处理HTTP Basic Authentication和忽略证书验证时的异同点。 背景介绍 假…

这套云原生开发工作流,让我3分钟上线。

我名义上是个全栈开发者&#xff0c;但最近感觉自己更像个“全栈救火队员”。一个前端组件&#xff0c;我可能半小时就写完了。但为了把它上线&#xff0c;我可能需要花一下午的时间&#xff0c;去跟 Nginx 配置、Docker 文件和CI/CD流水线搏斗。这个过程的挫败感&#xff0c;正…

ZGI 双向溯源:让 AI 的每一个回答都有据可查

为什么 RAG 依然会“自信地”胡说八道&#xff1f; 我们寄予厚望的 RAG&#xff08;检索增强生成&#xff09;技术&#xff0c;旨在通过引入外部知识来纠正大模型的“幻觉”。但在实践中&#xff0c;一个尴尬的局面屡见不鲜&#xff1a;RAG 系统精准地检索到了相关文档&#x…

Java Web 网上超市设计与实现系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着互联网技术的飞速发展&#xff0c;电子商务已成为现代商业活动的重要组成部分。网上超市作为一种便捷的购物方式&#xff0c;凭借其高效、灵活的特点&#xff0c;逐渐改变了传统零售业的格局。消费者对线上购物的需求日益增长&#xff0c;推动了网上超市系统的优化与创…

扔掉 K8s 和 YAML 后,我的团队上线速度快了 10 倍

我一直在思考一个问题&#xff1a;为什么在容器化如此普及的今天&#xff0c;部署应用依然是一件让许多团队头疼的难事&#xff1f;我们用 AI 加速了“写代码”&#xff0c;但工程师大量的时间&#xff0c;却消耗在了写代码之外的、那些看不见的“摩擦”上。我认为&#xff0c;…

Python OOP 设计思想 07:失败路径也是多态

在 Python 中&#xff0c;失败不是意外或错误&#xff0c;而是程序行为的一部分。多态不仅体现在成功路径上的可替换性&#xff0c;更体现在失败路径的可预测与可处理。理解失败的结构化语义&#xff0c;是掌握 Python 面向对象设计、构建健壮系统的关键。7.1 失败作为正常分支…

stm32L431+hal+freertos+lptime+tickless 进入stop模式失败记录(结果还是放弃了)

聊天记录的整理&#xff1a; STM32L4 FreeRTOS Tickless 模式下 LPTIM 无法唤醒问题排查总结 作者&#xff1a;sjh2100 & 千问 日期&#xff1a;2026年1月7日 适用平台&#xff1a;STM32L4 系列&#xff08;如 L476RG、L432KC 等&#xff09; 目标&#xff1a;实现 Stop 模…

SpringBoot+Vue 在线文档管理系统管理平台源码【适合毕设/课设/学习】Java+MySQL

摘要 随着信息化时代的快速发展&#xff0c;文档管理成为企业和个人高效工作的关键需求。传统的文档管理方式依赖本地存储和手动整理&#xff0c;存在易丢失、共享困难、版本混乱等问题。在线文档管理系统通过云端存储和协作功能&#xff0c;能够实现文档的集中管理、多用户协同…

Navicat 17 下载安装教程!

本文提供Navicat下载安装完整教程&#xff0c;从Navicat下载到Navicat安装完成&#xff0c;每个步骤都有详细图文说明。 一、Navicat 安装步骤详解 1、运行安装包 首先&#xff0c;找到下载好的 Navicat 17 安装包&#xff0c;右键选择【以管理员身份运行】。这一步很重要&…