C#学习第十七天(Xml文件,事件,Json文件)

一:Xml文件

1. 创建 XML 文档

// 创建 XmlDocument 对象
XmlDocument xml = new XmlDocument();

// 添加 XML 声明 (版本和编码)
XmlDeclaration dcl = xml.CreateXmlDeclaration("1.0", "UTF-8", null);
xml.AppendChild(dcl);

// 创建根节点
XmlElement root = xml.CreateElement("root");
xml.AppendChild(root);

2. 添加元素和属性

添加子元素:

// 创建 name 元素
XmlElement name = xml.CreateElement("name");
name.InnerText = "张三";  // 设置元素文本内容
root.AppendChild(name);   // 添加到根节点

// 添加属性
name.SetAttribute("id", "123456");  // <name id="123456">张三</name>

添加更多元素:

XmlElement age = xml.CreateElement("Age");
age.InnerText = "18";
root.AppendChild(age);

3. 保存 XML 文件

注:不写路径的情况下,会默认保存到当前运行程序的路径下

// 保存到文件
xml.Save("Xml项目文件.txt");  // 实际应使用 .xml 扩展名
Console.WriteLine("写入成功");

4. 读取 XML 文件

加载 XML 文件:

XmlDocument xml1 = new XmlDocument();
xml1.Load("Xml项目文件.txt");

访问节点数据:

// 获取根节点
XmlNode xn = xml1.DocumentElement;
Console.WriteLine(xn.Name);  // 输出: root

// 遍历子节点
foreach (XmlNode xn2 in xn.ChildNodes)
{
    Console.WriteLine(xn2.Name);      // 节点名称 (name, Age)
    Console.WriteLine(xn2.InnerText); // 节点内容 (张三, 18)
    
    // 读取属性
    if (xn2.Attributes != null && xn2.Attributes["id"] != null)
    {
        Console.WriteLine(xn2.Attributes["id"].Value);  // 输出: 123456
    }
}

二:事件

1. 基本概念

事件 vs 委托

  • 委托:类型安全的函数指针,可以存储多个方法引用

  • 事件:基于委托的封装,提供更安全的发布/订阅机制。基于委托的为委托提供一个发布/订阅的机制,可以说事件是一个具有特殊签名的委托。

  • 关键区别

    • 事件只能在声明它的类内部触发

    • 外部只能通过+=-=订阅/取消订阅

2. 代码结构分析

工具人类 (ToolMan):

public class ToolMan
{
    // 基础属性
    public string Name { get; set; }
    
    // 自定义委托定义(无参数无返回值)
    public delegate void DownDelgate();
    
    // 事件声明(基于自定义委托)
    public event DownDelgate downDelgate = null;
    
    // 使用系统预定义Action委托的事件(带string参数)
    public event Action<string> action;
    
    // 触发事件的方法
    public void Down()
    {
        Console.WriteLine($"{Name}下楼了");
        downDelgate();       // 触发无参数事件
        action("123");       // 触发带参数事件
    }
}

2. 懒人 (LazyMan) 类

public class LazyMan
{
    public string Name { get; set; }
    
    // 可被委托绑定的方法
    public void TakeFood() => Console.WriteLine($"{Name}买饭");
    public void GetFoot() => Console.WriteLine($"{Name}拿快递");
}

事件演示:

1. 事件订阅

ToolMan T = new ToolMan("怨种");
LazyMan L1 = new LazyMan("小明"), L2 = new LazyMan("小张");

// 多播委托订阅
T.downDelgate += L1.TakeFood;
T.downDelgate += L2.TakeFood;
T.downDelgate += L3.TakeFood;

// 取消订阅
T.downDelgate -= L3.TakeFood;

 2. 事件触发

T.Down();  // 正确触发方式
/* 输出:
   怨种下楼了
   小明买饭
   小张买饭
*/

3. Action事件使用

T.action += str => Console.WriteLine($"接收参数: {str}");
T.action("12300");  // 输出:接收参数: 12300

实例详解:

水温监控系统,当水温达到临界值时触发事件通知多个订阅者。

1. 事件发布者 (Class1 - 热水器类)

internal class Class1
{
    // 定义带int参数的事件
    public event Action<int> action;
    
    // 模拟烧水过程
    public void Boilwater()
    {
        for (int i = 0; i <= 100; i++)
        {
            if (i >= 95)  // 水温达到95度时触发事件
            {
                action(i);  // 传递当前温度值
            }
        }
    }
}

2. 事件订阅者(Class2 - 温度显示器)

internal class Class2
{
    public void ShowMsg(int param)
    {
        Console.WriteLine($"水温到了!当前水温{param}°C");
    }
}
Class3 - 智能报警器
internal class Class3
{
    public void MakeAi(int paras)
    {
        Console.WriteLine($"嘀嘀嘀:水已经{paras}°C,即将沸腾!");
    }
}

事件订阅与触发流程:

1. 创建对象实例:

Class1 c1 = new Class1();  // 热水器
Class2 c2 = new Class2();  // 显示器
Class3 c3 = new Class3();  // 报警器

2. 订阅事件:

c1.action += c2.ShowMsg;  // 显示器订阅温度事件
c1.action += c3.MakeAi;   // 报警器订阅温度事件

3. 触发事件

c1.Boilwater();  // 开始烧水过程

结果:

水温到了!当前水温95°C
嘀嘀嘀:水已经95°C,即将沸腾!
水温到了!当前水温96°C
嘀嘀嘀:水已经96°C,即将沸腾!
...
(持续到100°C)

三:如何使用Json文件

一、JSON 核心概念

1. JSON 基本结构(类似于字典,键值)

{
  "id": 123456,
  "name": "张三",
  "age": 18,
  "tags": [18, 20, 30],
  "stu": {
    "age": 18,
    "name": "张三"
  }
}

2. 使用 Newtonsoft.Json (Json.NET)

  • 最流行的 .NET JSON 处理库

  • 需通过 NuGet 安装:Install-Package Newtonsoft.Json

二、JSON 序列化与反序列化

普通数据:

创建Json数据:序列化,创建Json数据

JObject jsonObj = new JObject();

// 两种添加属性方式
jsonObj["name"] = "张三";          // 索引器方式
jsonObj.Add("id", 123456);        // Add 方法

// 添加数组
JArray colors = new JArray();
colors.Add("red");
colors.Add("blue");
jsonObj.Add("Color", colors);

// 输出 JSON 字符串
string jsonString = jsonObj.ToString();

 解析Json数据:反序列化 ,就是将Json数据 转回为原有类型

string jsonText = File.ReadAllText("data.json");
JObject parsedJson = JObject.Parse(jsonText);

// 获取值
string name = parsedJson["name"].ToString();
int id = (int)parsedJson["id"];

// 遍历数组
foreach (var color in parsedJson["Color"])
{
    Console.WriteLine(color);
}

对象:

类的定义:

public class Student
{
    public string Name { get; set; }
    public int Id { get; set; }
    public bool Sex { get; set; }
    public string Address { get; set; }
    
    // 需要无参构造函数供反序列化使用
    public Student() { }
    
    public Student(string name, int id, bool sex, string address)
    {
        Name = name;
        Id = id;
        Sex = sex;
        Address = address;
    }
}

 对象 ↔ JSON 转换

// 序列化对象 → JSON
Student stu1 = new Student("李四", 000000, true, "河南省郑州市高新区");
string json = JsonConvert.SerializeObject(stu1);

// 反序列化 JSON → 对象
Student stu = JsonConvert.DeserializeObject<Student>(json);

三、文件读写操作

1. 写入 JSON 文件

string path = string path = Directory.GetCurrentDirectory() + "\\Json数据.txt";
using (StreamWriter sw = new StreamWriter(path))
{
    sw.WriteLine(jsonString);
}

2. 读取 JSON 文件

string strjson;
using (StreamReader sr = new StreamReader(path))
{
    strjson = sr.ReadToEnd();
}
JObject strjson = JObject.Parse(strjson);//将Json数据格式的字符串 转化为Json对象

完整示例流程图:

[Student 对象]
    ↓ 序列化
[JSON 字符串]
    ↓ 写入文件
[data.json]
    ↓ 读取文件
[JSON 字符串]
    ↓ 反序列化
[Student 对象]

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值