在 C# 中,存储不同类型的数据有多种方式,具体选择取决于你的需求(类型安全、性能、灵活性等)。以下是常见的解决方案及其适用场景:

1. 使用 object 类型(装箱 / 拆箱)

将所有数据转换为基类 object,利用 C# 的多态性存储任意类型。

List<object> mixedList = new List<object>();
mixedList.Add(123);            // int → 装箱为object
mixedList.Add("Hello");        // string(引用类型无需装箱)
mixedList.Add(new DateTime()); // DateTime → 装箱为object
​
// 访问时需手动拆箱(可能引发InvalidCastException)
int num = (int)mixedList[0];   // 拆箱
string str = (string)mixedList[1];
  • 优点:简单直接,无需额外类型定义。

  • 缺点:

    • 装箱 / 拆箱开销:值类型(如 int, DateTime)频繁转换会降低性能。

    • 类型不安全:运行时可能抛出 InvalidCastException

2. 使用泛型集合 List<dynamic>

dynamic 关键字在运行时动态解析类型,避免编译时类型检查。List<dynamic> dynamicList = new List<dynamic>();
dynamicList.Add(123);        // 无需装箱
dynamicList.Add("Hello");
dynamicList.Add(new { Name = "Alice" }); // 匿名类型也可存储
​
// 访问时无需显式转换
int num = dynamicList[0];    // 动态类型解析
string str = dynamicList[1];
  • 优点:

    • 无需装箱拆箱(值类型以原始类型存储)。

    • 支持匿名类型等复杂结构。

  • 缺点:

    • 运行时类型风险:若类型不匹配会在运行时抛出异常。

    • 性能开销:动态解析比静态类型稍慢。

3. 使用自定义类 / 结构体(推荐方案)

public class MixedData
{public int Id { get; set; }public string Name { get; set; }public DateTime BirthDate { get; set; }
}
​
// 使用方式
List<MixedData> dataList = new List<MixedData>();
dataList.Add(new MixedData { Id = 1, Name = "Alice", BirthDate = DateTime.Now 
});

定义一个包含所需字段的类,每个字段使用明确的类型。

public class MixedData
{public int Id { get; set; }public string Name { get; set; }public DateTime BirthDate { get; set; }
}
​
// 使用方式
List<MixedData> dataList = new List<MixedData>();
dataList.Add(new MixedData { Id = 1, Name = "Alice", BirthDate = DateTime.Now 
});
  • 优点:

    • 类型安全:编译时检查类型。

    • 可读性高:字段含义明确。

    • 性能最优:无需装箱拆箱。

  • 缺点:需提前定义类型,不够灵活。

4. 使用 TupleValueTuple

适合临时存储少量不同类型的数据。// Tuple(旧版,需通过Item1、Item2访问)
var tupleList = new List<Tuple<int, string>>();
tupleList.Add(Tuple.Create(1, "Alice"));
​
// ValueTuple(C# 7.0+,推荐,支持命名元素)
var valueTupleList = new List<(int Id, string Name)>();
valueTupleList.Add((1, "Alice"));
​
// 访问方式
int id = valueTupleList[0].Id;
string name = valueTupleList[0].Name;
  • 优点:简洁,无需额外类定义。

  • 缺点:

    • 元素数量有限(最多 8 个)。

    • 不适合复杂或大量数据。

5. 使用 Dictionary<string, object>

以键值对形式存储不同类型的值,类似动态对象。

var dict = new Dictionary<string, object>();
dict["Id"] = 123;
dict["Name"] = "Alice";
dict["IsActive"] = true;
​
// 访问时需转换类型
int id = (int)dict["Id"];
bool isActive = (bool)dict["IsActive"];
  • 优点:灵活,可动态添加 / 删除键值对。

  • 缺点:

    • 类型不安全,需手动转换。

    • 键名硬编码,易出错。

6. 使用接口或抽象类(面向对象设计)

定义公共接口,让不同类型实现该接口。

public interface IDataItem { }
​
public class Person : IDataItem
{public string Name { get; set; }
}
​
public class Product : IDataItem
{public decimal Price { get; set; }
}
​
// 使用方式
List<IDataItem> items = new List<IDataItem>();
items.Add(new Person { Name = "Alice" });
items.Add(new Product { Price = 9.99m });
​
// 通过模式匹配访问
foreach (var item in items)
{if (item is Person person)Console.WriteLine(person.Name);else if (item is Product product)Console.WriteLine(product.Price);
}
  • 优点:

    • 类型安全,符合面向对象原则。

    • 可扩展,易于添加新类型。

  • 缺点:需设计接口和继承体系,复杂度较高。

7. 使用 ExpandoObject(动态对象)

System.Dynamic.ExpandoObject 是动态类型的字典,支持运行时添加属性。

dynamic person = new ExpandoObject();
person.Name = "Alice";
person.Age = 30;
​
// 直接访问属性(无需转换)
Console.WriteLine(person.Name); // "Alice"
  • 优点:

    • 语法简洁,像普通对象一样访问属性。

    • 无需提前定义类型。

  • 缺点:

    • 编译时无类型检查,易出错。

    • 性能略低于静态类型。

    7. ArrayList(非泛型,不推荐)

    特点

    • 来自 System.Collections 命名空间,可存储任意类型(实际存为 object)。

    • 动态扩容,但存在装箱 / 拆箱开销类型安全问题

    示例

    using System.Collections;
    ​
    ArrayList list = new ArrayList();
    list.Add("张三");    // string → object(装箱)
    list.Add(10);        // int → object(装箱)
    list.Add(2.2);       // double → object(装箱)
    ​
    // 访问时需手动拆箱,可能引发InvalidCastException
    int num = (int)list[1]; // 拆箱
方案装箱开销类型安全性能(相对)
List<object>
List<dynamic>
自定义类 / 结构体
Dictionary<string, object>
ExpandoObject中低
ArrayList

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

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

相关文章

超唯美治愈风卡通插画PPT模版

海洋卡通风治愈系PPT模版&#xff0c;儿童可爱治愈可爱PPT模版&#xff0c;治愈风商务通用PPT模版&#xff0c;治愈系课件PPT模版&#xff0c;治愈风插画PPT模版&#xff0c;超唯美治愈风PPT模版&#xff0c;可爱插画治愈系女孩PPT模版 超唯美治愈风卡通插画PPT模版&#xff1a…

el-tooltip 快速滚动的时候出现残影如何解决 vue3

<el-tooltip:disabled"isScrolling" <!-- 新增滚动状态绑定 -->:popper-options"{ modifiers: [{ name: computeStyles, options: { adaptive: false }] }"effect"dark":content"label.name"placement"right-start"…

【经典面经】C++新特性 TCP完整收发数据 TLS1.2 TLS1.3

文章目录cpp新特性C11C14C17C20tcp如何保证完整收发数据结论1. **面向连接的三次握手**2. **字节序号与确认机制**3. **校验和&#xff08;Checksum&#xff09;**4. **超时重传与快速重传**5. **滑动窗口&#xff08;流量控制&#xff09;**6. **数据重组与排序**7. **四次挥手…

Spring AI 系列之十一 - RAG-进阶RetrievalAugmentationAdvisor

之前做个几个大模型的应用&#xff0c;都是使用Python语言&#xff0c;后来有一个项目使用了Java&#xff0c;并使用了Spring AI框架。随着Spring AI不断地完善&#xff0c;最近它发布了1.0正式版&#xff0c;意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说…

[TOOL] ubuntu 使用 ffmpeg 操作 gif、mp4

文章目录一、工具安装二、gif 转mp4三、mp4 两倍速一、工具安装 安装 ffmpeg 工具&#xff1a; sudo apt install ffmpeg二、gif 转mp4 1. 配置环境 核心指令: ffmpeg -i input.mp4 -filter_complex "[0:v]setpts0.5*PTS[v];[0:a]atempo2.0[a]" -map "[v]&q…

linux中INIT_MM_CONTEXT宏对pgd的重复赋值

在GNU C中&#xff0c;支持通过标号元素对指定结构体成员名进行初始化&#xff0c;这允许初始化值以任意顺序出现。在linux内核中对init_mm初始化时有如下代码。#define INIT_MM_CONTEXT(name) \.pgd init_pg_dir,struct mm_struct init_mm {.mm_rb RB_ROOT,.pgd swapper…

第十五章 STL(stack、queue、list、set、map容器使用)

栈stack使用&#xff1a;队列queue双向循环链表listlist构造函数list 赋值和交换list 大小操作list 插入和删除list 数据存取list 反转和排序排序算法sort降序操作排序案例#include<iostream> using namespace std; #include<list>class Person { private:string n…

【论文阅读】HCCF:Hypergraph Contrastive Collaborative Filtering

论文出处&#xff1a;SIGIR 2022 CCF-A 论文地址&#xff1a;Hypergraph Contrastive Collaborative Filtering 论文代码&#xff1a;akaxlh/HCCF: HCCF, SIGIR 2022 目录 摘要 介绍 研究背景与核心问题 现有方法局限性 HCCF的创新解决方案 技术优势 定义与相关工作 …

Retrofit+RxJava:打造声明式REST客户端的艺术 —— 像点咖啡一样调用API

目录一、告别Callback地狱&#xff1a;声明式编程的魅力1.1 传统网络请求的痛点1.2 Retrofit的声明式革命二、Retrofit核心配置工厂2.1 构建Retrofit实例2.2 常用注解速查表三、RxJava响应式魔法3.1 链式调用优雅变身3.2 超能力操作符盘点四、实战演练&#xff1a;构建天气查询…

【离线数仓项目】——任务调度与数据可视化实战

摘要 本文主要围绕离线数仓项目中的任务调度与数据可视化实战展开&#xff0c;介绍了业务流程虚拟节点、离线数仓任务调度、数据可视化等方面的内容&#xff0c;涉及DataWorks和QuickBI等工具的使用&#xff0c;并提供了相关的博文参考和项目实战域信息。 1. 任务调度管理实战…

【视频格式转换】.264格式转为mp4格式

背景 视频格式转换是多媒体处理中的常见需求&#xff0c;尤其在视频编辑、存储或跨平台播放时。H.264&#xff08;即AVC&#xff09;是一种广泛使用的视频编码标准&#xff0c;以其高压缩率和良好兼容性著称&#xff0c;但通常以容器格式&#xff08;如.264裸流文件&#xff0…

JAVA学习笔记 使用notepad++开发JAVA-003

目录 1 前言 2 部署notepad的java开发环境 2.1 下载并安装notepad 2.2 设置新建文件的语言 2.3 安装NppExec插件 2.4 编写JAVA脚本 2.5 设置脚本执行快捷键 2.6 效果测试 3 小结 1 前言 JAVA可以使用记事本来编写代码&#xff0c;但是这种方式效率十分低下。我们可以使…

Vue Router 完全指南:从入门到实战,高效管理前端路由

前言在现代化的前端开发中&#xff0c;路由管理是构建单页应用&#xff08;SPA&#xff09;的核心功能之一。Vue.js 作为主流的前端框架之一&#xff0c;提供了强大的官方路由库Vue Router&#xff0c;帮助开发者高效管理页面跳转、动态加载、权限控制等关键需求。无论是构建企…

Sentinel热点参数限流完整示例实现

Sentinel热点参数限流完整示例实现 1. 添加Maven依赖 (pom.xml) <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId><version>2.2.7.RELEASE</version> </depend…

正则表达式深度解析:从LeetCode 3136题说起

正则表达式深度解析&#xff1a;从LeetCode 3136题说起 引言 正则表达式&#xff08;Regular Expression&#xff0c;简称RegEx&#xff09;是一种强大的字符串匹配工具&#xff0c;在字符串处理、数据验证、文本搜索等场景中有着广泛的应用。本文将以LeetCode 3136题"有效…

映美打印机-URL页面打印

<?php /** 打印 - 映美云 https://open.jolimark.com/doc/ */ namespace Home\Controller; use Admin\Logic\OrderLogic;class PrintController extends BaseController {private $appid "";private $appkey "";//打印机编号private $deviceIds &qu…

机器学习算法 ——XGBoost 的介绍和使用

前言&#xff1a; 最近在工作中遇到一个结构化数据回归预测的问题&#xff0c;用到了很多回归算法&#xff08;如多元线性回归等&#xff09;都没有很好的效果&#xff0c;于是使用了XGBoost&#xff0c;自己也冲三个特征参数人为的增加来几个&#xff0c;训练出来的效果还是很…

Linux操作系统之信号:保存与处理信号

目录 前言&#xff1a; 前文回顾与补充&#xff1a; 信号的保存 PCB里的信号保存 sigset_t 信号集操作函数 信号的处理 信号捕捉的流程&#xff1a;​编辑 操作系统的运行原理 硬件中断 时钟中断 死循环 软中断 总结&#xff1a; 前言&#xff1a; 在上一篇文…

Spring Boot 设置滚动日志logback

Spring Boot 的 logback 框架 Spring Boot 默认内置了 Logback 作为日志实现框架&#xff0c;只需要在resources文件夹下添加一个logback-spring.xml&#xff0c;springboot会按照你的设置自动开启logback日志功能。 配置 logback-spring.xml 实现每天产生一个日志文件&#xf…

如何定义一个只能在堆上或栈上生成对象的类

在C中&#xff0c;可以通过特定的技术手段来控制对象只能在堆(heap)或栈(stack)上创建。只能在堆上创建对象的类要实现这一点&#xff0c;我们需要阻止用户直接实例化对象&#xff0c;而只能通过new操作符创建。class HeapOnly { public:static HeapOnly* create() {return new…