4人参与 • 2026-03-20 • Asp.net
在c#开发中,数据序列化与反序列化是高频需求,广泛应用于配置文件、数据传输、日志存储等场景。yaml作为简洁易读的非标记语言,相比xml繁琐、json紧凑的特点,更适合作为配置文件和高可读性的数据交换格式。而yamldotnet作为c#生态最主流的yaml处理类库,开源免费、功能强大,是处理yaml数据的首选工具。本文聚焦实战,从核心定位、环境搭建、基础用法到进阶技巧,帮你快速掌握yamldotnet全流程用法。
yamldotnet是基于mit许可证的开源c#类库,核心功能是实现.net对象与yaml格式的双向转换(序列化/反序列化),底层封装了yaml语法解析器与生成器,提供简洁api,支持自定义规则,适配复杂业务场景。
| 类库 | 核心优势 | 不足 | 选型建议 |
|---|---|---|---|
| yamldotnet | 专注yaml,易用性强、扩展灵活,支持注释和复杂类型 | 序列化速度略逊于newtonsoft.json,不支持json | 配置文件、高可读性数据交换首选 |
| newtonsoft.json | 速度快、功能丰富、生态完善,专注json | 不支持yaml,配置文件可读性差 | json数据传输、接口交互场景 |
| system.xml.serialization | 内置无依赖,适配传统xml配置 | 语法繁琐、扩展性低,不支持yaml | 旧项目xml配置兼容场景 |
| sharpyaml | 轻量、解析快,支持yaml 1.2 | 社区活跃低、高级功能不完善 | 简单yaml解析场景,不推荐复杂项目 |
yamldotnet为第三方类库,需通过nuget安装,搭建流程简单,适配所有.net版本。
visual studio → 右键项目 → 管理nuget程序包 → 搜索“yamldotnet” → 安装最新稳定版。
install-package yamldotnet -version 13.7.1 # 可替换为最新版本
<itemgroup> <packagereference include="yamldotnet" version="13.7.1" /> </itemgroup>
using yamldotnet; using yamldotnet.serialization; using yamldotnet.serialization.namingconventions;
编写简单代码,验证序列化与反序列化功能是否正常:
// 1. 定义测试类
public class user
{
public string name { get; set; }
public int age { get; set; }
public list<string> hobbies { get; set; }
}
// 2. 序列化(对象→yaml)
var user = new user { name = "zhangsan", age = 25, hobbies = new list<string> { "coding", "reading" } };
var serializer = new serializerbuilder()
.withnamingconvention(camelcasenamingconvention.instance)
.build();
string yaml = serializer.serialize(user);
console.writeline("序列化结果:\n" + yaml);
// 3. 反序列化(yaml→对象)
var deserializer = new deserializerbuilder()
.withnamingconvention(camelcasenamingconvention.instance)
.ignoreunmatchedproperties()
.build();
user deserializeduser = deserializer.deserialize<user>(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<string, int> { { "math", 90 }, { "english", 85 } }
};
// 序列化
string yaml = serializer.serialize(data);
// 反序列化(dynamic类型,无需定义实体类)
dynamic deserialized = deserializer.deserialize<dynamic>(yaml);
console.writeline($"math score: {deserialized.scores.math}");支持自定义类、继承类、嵌套类的序列化与反序列化:
// 嵌套类
public class address { public string province { get; set; } public string city { get; set; } }
// 父类
public class person { public string name { get; set; } public int age { get; set; } }
// 子类
public class student : person
{
public string studentid { get; set; }
public address address { get; set; }
public list<string> courses { get; set; }
}
// 序列化
var student = new student
{
name = "wangwu",
age = 20,
studentid = "2023001",
address = new address { province = "guangdong", city = "shenzhen" },
courses = new list<string> { "c#", "database" }
};
string studentyaml = serializer.serialize(student);
// 反序列化
student deserializedstudent = deserializer.deserialize<student>(studentyaml);通过特性自定义单个属性的序列化规则,灵活适配需求:
using yamldotnet.serialization.attributes;
public class product
{
[yamlalias("product_id")] // 别名,yaml中显示为product_id
public string id { get; set; }
[yamlignore] // 忽略该属性,不序列化/反序列化
public string secret { get; set; }
[yamlcomment("产品名称(必填)")] // 添加注释
public string name { get; set; }
[yamlmember(order = 1)] // 指定序列化顺序
public decimal price { get; set; }
}基础用法可满足简单场景,企业级项目需解决复杂类型、性能、稳定性等问题,以下是核心技巧。
针对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<scalar>().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文件的双向读写:
/// <summary>
/// 序列化对象到yaml文件
/// </summary>
public void serializetofile(object obj, string filepath)
{
using (var writer = new streamwriter(filepath, false, encoding.utf8))
{
serializer.serialize(writer, obj);
}
}
/// <summary>
/// 从yaml文件反序列化到对象
/// </summary>
public t deserializefromfile<t>(string filepath)
{
if (!file.exists(filepath)) throw new filenotfoundexception("yaml文件不存在", filepath);
using (var reader = new streamreader(filepath, encoding.utf8))
{
return deserializer.deserialize<t>(reader);
}
}完善异常处理,避免程序崩溃,提升稳定性:
public t deserializewithexceptionhandling<t>(string yaml)
{
try
{
return deserializer.deserialize<t>(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;
}
}结合前文知识点,实现可直接复用的yaml配置读写工具,适配项目全局配置场景。
yamlconfigdemo/ ├─ config/ │ ├─ appconfig.cs(配置实体) │ └─ yamlconfighelper.cs(工具类) ├─ appsettings.yaml(配置文件) └─ program.cs(测试入口)
using yamldotnet.serialization.attributes;
namespace yamlconfigdemo.config
{
public class appconfig
{
[yamlcomment("应用名称(必填)")]
public string appname { get; set; }
[yamlcomment("应用版本")]
public string version { get; set; }
[yamlcomment("数据库配置")]
public databaseconfig database { get; set; }
[yamlcomment("服务配置")]
public serviceconfig service { get; set; }
}
public class databaseconfig
{
[yamlalias("connection_string")]
public string connectionstring { get; set; }
[yamlalias("timeout")]
public int timeout { get; set; } = 30;
}
public class serviceconfig
{
[yamlalias("base_url")]
public string baseurl { get; set; }
[yamlalias("timeout")]
public int timeout { get; set; } = 5000;
}
}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<t>(string filepath)
{
if (!file.exists(filepath)) throw new filenotfoundexception("配置文件不存在", filepath);
using (var reader = new streamreader(filepath, encoding.utf8))
{
return _deserializer.deserialize<t>(reader);
}
}
// 写入配置
public static void writeconfig(object config, string filepath)
{
using (var writer = new streamwriter(filepath, false, encoding.utf8))
{
_serializer.serialize(writer, config);
}
}
}
}using yamlconfigdemo.config;
// 写入配置
var config = new appconfig
{
appname = "yamldotnetdemo",
version = "1.0.0",
database = new databaseconfig
{
connectionstring = "server=localhost;database=test;uid=root;pwd=123456;"
},
service = new serviceconfig
{
baseurl = "https://api.demo.com"
}
};
yamlconfighelper.writeconfig(config, "appsettings.yaml");
// 读取配置
var readconfig = yamlconfighelper.readconfig<appconfig>("appsettings.yaml");
console.writeline($"应用名称:{readconfig.appname}");
console.writeline($"数据库连接串:{readconfig.database.connectionstring}");yamldotnet是c#处理yaml数据的最优选择,其易用性、灵活性和兼容性,能完美适配配置文件、数据交换等各类场景。本文从基础到进阶,覆盖环境搭建、核心用法、优化技巧和实战案例,代码可直接复用。掌握本文内容,可轻松解决yaml序列化/反序列化的各类问题,提升开发效率。
到此这篇关于c#常用类库yamldotnet详解的文章就介绍到这了,更多相关c#常用类库yamldotnet内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论