在C#开发中,数据序列化与反序列化是高频需求,广泛应用于配置文件、数据传输、日志存储等场景。YAML作为简洁易读的非标记语言,相比XML繁琐、JSON紧凑的特点,更适合作为配置文件和高可读性的数据交换格式。而YamlDotNet作为C#生态最主流的YAML处理类库,开源免费、功能强大,是处理YAML数据的首选工具。本文聚焦实战,从核心定位、环境搭建、基础用法到进阶技巧,帮你快速掌握YamlDotNet全流程用法。
YamlDotNet是基于MIT许可证的开源C#类库,核心功能是实现.NET对象与YAML格式的双向转换(序列化/反序列化),底层封装了YAML语法解析器与生成器,提供简洁API,支持自定义规则,适配复杂业务场景。
- 开源免费:可自由用于商业项目,源码可定制,社区活跃,适配.NET全框架(.NET Framework 4.5+、.NET Core 2.0+、.NET 5+)。
- 功能完整:支持基本类型、自定义类、集合、泛型、继承类的序列化/反序列化,兼容YAML 1.1和1.2规范。
- 灵活可扩展:支持自定义序列化规则、属性映射、忽略指定属性、保留注释,适配复杂业务场景。
- 兼容性强:跨平台支持(Windows、Linux、macOS),无第三方依赖,集成简单。
- 性能优异:解析速度快、内存占用低,支持大数据量YAML文档处理,满足企业级需求。
- 配置文件:替代XML、JSON,作为appsettings.yaml等配置文件,便于人工编辑。
- 数据交换:微服务、跨语言项目中,作为高可读性的数据交换格式。
- 日志存储:将复杂日志对象序列化为YAML,便于分析查看。
- 文档生成:生成YAML格式接口文档、K8s配置文件等。
- 数据导入导出:实现系统数据的备份与恢复。
YamlDotNet为第三方类库,需通过NuGet安装,搭建流程简单,适配所有.NET版本。
方式1:NuGet界面安装
Visual Studio → 右键项目 → 管理NuGet程序包 → 搜索“YamlDotNet” → 安装最新稳定版。
方式2:Package Manager Console命令
Install-Package YamlDotNet -Version 13.7.1 # 可替换为最新版本
方式3:手动修改.csproj文件
using YamlDotNet; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions;
编写简单代码,验证序列化与反序列化功能是否正常:
// 1. 定义测试类 public class User public int Age public List
Hobbies } // 2. 序列化(对象→YAML) var user = new User { Name = "ZhangSan", Age = 25, Hobbies = new List
{ "Coding", "Reading" } }; var serializer = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .Build(); string yaml = serializer.Serialize(user); Console.WriteLine("序列化结果: " + yaml); // 3. 反序列化(YAML→对象) var deserializer = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .IgnoreUnmatchedProperties() .Build(); User deserializedUser = deserializer.Deserialize
(yaml); Console.WriteLine($"反序列化结果:Name={deserializedUser.Name}, Age={deserializedUser.Age}");
运行程序,正常输出结果即说明环境搭建成功。
YamlDotNet的核心的是序列化与反序列化,以下覆盖常用场景,代码可直接复制使用。
序列化器与反序列化器的常用配置,统一配置可提升代码复用性:
// 序列化器配置 var serializer = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) // 驼峰命名 .Indent(2) // 缩进2个空格 .WithCommentHandling(CommentHandling.IncludeComments) // 保留注释 .Build(); // 反序列化器配置 var deserializer = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .IgnoreUnmatchedProperties() // 忽略未知属性,避免报错 .AllowNullValues() // 允许空值 .Build();
支持string、int、DateTime等基本类型,以及List、Dictionary等集合:
var data = new { Name = "LiSi", Age = 30, BirthDate = new DateTime(1993, 10, 1), Tags = new string[] { "C#", "YamlDotNet" }, Scores = new Dictionary
{ { "Math", 90 }, { "English", 85 } } }; // 序列化 string yaml = serializer.Serialize(data); // 反序列化(dynamic类型,无需定义实体类) dynamic deserialized = deserializer.Deserialize
(yaml); Console.WriteLine($"Math Score: {deserialized.scores.math}");
支持自定义类、继承类、嵌套类的序列化与反序列化:
// 嵌套类 public class Address public string City } // 父类 public class Person public int Age } // 子类 public class Student : Person public Address Address public List
Courses } // 序列化 var student = new Student { Name = "WangWu", Age = 20, StudentId = "", Address = new Address { Province = "Guangdong", City = "Shenzhen" }, Courses = new List
{ "C#", "Database" } }; string studentYaml = serializer.Serialize(student); // 反序列化 Student deserializedStudent = deserializer.Deserialize
(studentYaml);
通过特性自定义单个属性的序列化规则,灵活适配需求:
using YamlDotNet.Serialization.Attributes; public class Product [YamlIgnore] // 忽略该属性,不序列化/反序列化 public string Secret [YamlComment("产品名称(必填)")] // 添加注释 public string Name [YamlMember(Order = 1)] // 指定序列化顺序 public decimal Price }
基础用法可满足简单场景,企业级项目需解决复杂类型、性能、稳定性等问题,以下是核心技巧。
针对DateTime、Enum等复杂类型,自定义转换规则(以DateTime格式化为例):
// 实现自定义转换器 public class CustomDateTimeConverter : IYamlTypeConverter { public bool Accepts(Type type) => type == typeof(DateTime) || type == typeof(DateTime?); // 反序列化:字符串→DateTime public object ReadYaml(IParser parser, Type type) { var value = parser.Consume
().Value; return DateTime.ParseExact(value, "yyyy-MM-dd HH:mm:ss", null); } // 序列化:DateTime→字符串 public void WriteYaml(IEmitter emitter, object value, Type type) { emitter.Emit(new Scalar(((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"))); } } // 注册并使用 var serializer = new SerializerBuilder() .WithTypeConverter(new CustomDateTimeConverter()) .Build();
封装工具方法,实现对象与YAML文件的双向读写:
////// 序列化对象到YAML文件 /// public void SerializeToFile(object obj, string filePath) { using (var writer = new StreamWriter(filePath, false, Encoding.UTF8)) { serializer.Serialize(writer, obj); } } ////// 从YAML文件反序列化到对象 /// public T DeserializeFromFile(string filePath) }
(1)异常处理
完善异常处理,避免程序崩溃,提升稳定性:
public T DeserializeWithExceptionHandling
(string yaml) { try { return deserializer.Deserialize
(yaml); } catch (YamlException ex) { Console.WriteLine($"YAML语法错误:{ex.Message},行号:{ex.Start.Line}"); return default; } catch (InvalidCastException ex) { Console.WriteLine($"类型转换错误:{ex.Message}"); return default; } catch (Exception ex) { Console.WriteLine($"反序列化失败:{ex.Message}"); return default; } }
(2)性能优化(大数据量场景)
- 使用Stream读写,减少内存占用;
- 复用序列化器/反序列化器实例(单例模式);
- 禁用不必要的功能(如注释处理);
- 避免使用dynamic类型,优先使用具体类型。
- 坑1:YAML语法错误:缩进用空格(不支持Tab),冒号、横杠后必须加空格;用在线工具校验语法。
- 坑2:命名不一致:序列化与反序列化配置相同的命名约定,或用[YamlAlias]指定别名。
- 坑3:复杂类型格式不符:实现自定义类型转换器,或使用内置配置。
- 坑4:未知属性报错:配置IgnoreUnmatchedProperties()忽略未知属性。
- 坑5:大数据量性能差:用Stream、复用实例、禁用注释处理。
- 统一命名约定,保持序列化与反序列化配置一致;
- 复用序列化器/反序列化器实例,提升性能;
- 敏感字段用[YamlIgnore]忽略,关键属性加注释;
- 配置文件场景保留注释,便于维护;
- 序列化后校验YAML语法,避免反序列化失败。
结合前文知识点,实现可直接复用的YAML配置读写工具,适配项目全局配置场景。
YamlConfigDemo/ ├─ Config/ │ ├─ AppConfig.cs(配置实体) │ └─ YamlConfigHelper.cs(工具类) ├─ appsettings.yaml(配置文件) └─ Program.cs(测试入口)
(1)配置实体类(AppConfig.cs)
using YamlDotNet.Serialization.Attributes; namespace YamlConfigDemo.Config
[YamlComment("应用版本")] public string Version [YamlComment("数据库配置")] public DatabaseConfig Database [YamlComment("服务配置")] public ServiceConfig Service } public class DatabaseConfig [YamlAlias("timeout")] public int Timeout = 30; } public class ServiceConfig [YamlAlias("timeout")] public int Timeout = 5000; }
}
(2)配置读写工具类(YamlConfigHelper.cs)
using System.IO; using System.Text; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; namespace YamlConfigDemo.Config {
public static class YamlConfigHelper { // 单例复用实例 private static readonly Serializer _serializer; private static readonly Deserializer _deserializer; static YamlConfigHelper() { _serializer = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .WithCommentHandling(CommentHandling.IncludeComments) .Indent(4) .Build(); _deserializer = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .IgnoreUnmatchedProperties() .AllowNullValues() .Build(); } // 读取配置 public static T ReadConfig
(string filePath) } // 写入配置 public static void WriteConfig(object config, string filePath) { using (var writer = new StreamWriter(filePath, false, Encoding.UTF8)) { _serializer.Serialize(writer, config); } } }
}
(3)测试使用(Program.cs)
using YamlConfigDemo.Config; // 写入配置 var config = new AppConfig {
AppName = "YamlDotNetDemo", Version = "1.0.0", Database = new DatabaseConfig { ConnectionString = "Server=localhost;Database=Test;Uid=root;Pwd=;" }, Service = new ServiceConfig { BaseUrl = "https://api.demo.com" }
}; YamlConfigHelper.WriteConfig(config, “appsettings.yaml”); // 读取配置 var readConfig = YamlConfigHelper.ReadConfig
YamlDotNet是C#处理YAML数据的最优选择,其易用性、灵活性和兼容性,能完美适配配置文件、数据交换等各类场景。本文从基础到进阶,覆盖环境搭建、核心用法、优化技巧和实战案例,代码可直接复用。掌握本文内容,可轻松解决YAML序列化/反序列化的各类问题,提升开发效率。
到此这篇关于C#常用类库YamlDotNet详解的文章就介绍到这了,更多相关C#常用类库YamlDotNet内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/245801.html