.NET
基于 .NET 软件框架的 Microsoft 技术。
94 个问题
你好!
在我的应用里,使用了System.Text.Json里的反序列化,类实例接受反序列化结果后,类中监测变量改变的事件将不会触发,我用其它代码实现反序列化,事件就会正常触发。是我使用的问题还是这里面存在Bug?
谢谢你的帮助!
C#用户
2025-3-28
remote_io = JsonSerializer.Deserialize<MyClass>(str); //使用这行出问题,用下面三行替换就正常
//string[] substr = str.Split(new char[2] { ':', ',' });
//remote_io.output = substr[3].Substring(1, 8); ;
//remote_io.input = substr[5].Substring(1, 8); ;
以下是部分相关的代码:
public Form1()
{
//CheckForIllegalCrossThreadCalls = false;//为在其它纯种中可调用窗体控件
//如果为Ture;可用this.BeginInvoke(new Action(delegate (){}));//在线程里刷新UI界面
InitializeComponent();
remote_io = new MyClass();
remote_io.output = "00000000";
remote_io.OnMyValueChanged += myclase_OnMyValueChanged;
}
类中变量改变监测事件
void myclase_OnMyValueChanged(object sender, EventArgs e)
{
//当变量值发生变化的时候,执行
if (remote_io.OUT1) btOUT1.BackColor = Color.Green;
else btOUT1.BackColor = Color.Red;
}
}
private void btConnect_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
threadClient = new Thread(() =>
{
IPEndPoint ipendpoint = new IPEndPoint(IPAddress.Any, 8998);
while (!cts.IsCancellationRequested)
{
try
{
if (udpclient.Available <= 0) { Thread.Sleep(100); continue; }//判断是否有网络数据
if (udpclient.Client == null) return;//判断连接是否为空
//调用UdpClient对象的Receive方法获得从远程主机返回的UDP数据报
byte[] bytes = udpclient.Receive(ref ipendpoint);
//将获得的UDP数据报转换为字符串形式
string str = Encoding.Default.GetString(bytes); //返回格式:{"cmd":"setr","output":"10111111","input":"00000000","humidity":43.8,"centigrade":26.5,"fahrenheit":79.70,"runtime":1303,"timestamp":0,"sn":"V59f09ad589e9719"}
remote_io = JsonSerializer.Deserialize<MyClass>(str); //使用这行出问题,用下面三行替换就正常
//string[] substr = str.Split(new char[2] { ':', ',' });
//remote_io.output = substr[3].Substring(1, 8); ;
//remote_io.input = substr[5].Substring(1, 8); ;
this.BeginInvoke(new Action(delegate ()
{ // }));//在线程里刷新UI界面
rtbRecive.Text += "\n" + str;//显示接收的所有数据
//JSON反序列化
rtbRecive.Text += "\nIO输出:" + remote_io.output;//显示接收的所有数据
rtbRecive.Text += "\n湿度:" + remote_io.humidity;//显示接收的所有数据
rtbRecive.Text += "\n温度" + remote_io.centigrade;//显示接收的所有数据
rtbRecive.Text += "\nOUT1:" + remote_io.OUT1;//显示接收的所有数据
rtbRecive.Text += "\nIN1:" + remote_io.IN1;//显示接收的所有数据
}));//在线程里刷新UI界面
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);//错误提示
}
}
});
threadClient.IsBackground = true;
rtbRecive.Clear();
threadClient.Start();
rtbRecive.AppendText("客户端接收已经开启");
btConnect.Enabled = false;
}
接收到的数据格式
json
{"cmd":"setr","output":"10111111","input":"00000000","humidity":43.8,"centigrade":26.5,"fahrenheit":79.70,"runtime":1303,"timestamp":0,"sn":"V59f09ad589e9719"}
接收反序列化的类
class MyClass
{
private string _input;
public string input
{ get=>_input;
set
{
_input = value;
IN1 = _input[0] == '1' ? true : false;
IN2 = _input[1] == '1' ? true : false;
// 触发事件
//OnMyValueChanged?.Invoke(this, OUT1);
WhenMyValueChange();
}
}
。。。。
//定义的委托
public delegate void MyValueChanged(object sender, EventArgs e);
//与委托相关联的事件
public event MyValueChanged OnMyValueChanged;
//事件触发函数
private void WhenMyValueChange()
{
if (OnMyValueChanged != null)
{
OnMyValueChanged(this, null);
}
}
}
(完)
System.Text.Json
反序列化时 不会调用属性的 setter,导致事件不触发。
尝试在 OnDeserialized
事件后手动触发 setter。
using System.Text.Json;
using System.Text.Json.Serialization;
class MyClass
{
private string _input;
public string input
{
get => _input;
set
{
_input = value;
IN1 = _input[0] == '1';
IN2 = _input[1] == '1';
WhenMyValueChange();
}
}
public bool IN1 { get; private set; }
public bool IN2 { get; private set; }
public event EventHandler OnMyValueChanged;
private void WhenMyValueChange()
{
OnMyValueChanged?.Invoke(this, EventArgs.Empty);
}
[JsonConstructor]
public MyClass(string input)
{
this.input = input; // 调用 setter 以触发事件
}
public MyClass() { } // 需要无参构造函数
}
如果答案是正确的,请点击“接受答案”并点赞。 如果您对此答案还有其他疑问,请点击“评论”。
注意:如果您想接收相关电子邮件,请按照我们的文档中的步骤启用电子邮件通知 此线程的通知。