C#中已存储数据的类间变量传递与更新问题(Modbus TCP场景)
问题分析与解决方案
问题根源
核心问题是**Modbus类和Server_Socket类各自实例化了独立的Modbus_Variables对象**,两者属于不同内存实例,因此Modbus中赋值的Function_Code不会同步到Server_Socket的实例里,自然取到默认值0。
优化的跨类/跨项目共享变量方案
1. 单例模式(全局共享最直接方案)
修改Modbus_Variables为单例,确保整个应用只有一个实例:
public class Modbus_Variables { // 私有构造函数禁止外部实例化 private Modbus_Variables() {} // 懒加载式静态实例,保证线程安全 private static readonly Lazy<Modbus_Variables> _instance = new Lazy<Modbus_Variables>(() => new Modbus_Variables()); public static Modbus_Variables Instance => _instance.Value; public byte Function_Code { get; set; } }
在Modbus和Server_Socket中直接使用单例实例:
// Modbus类中 public class Modbus { private readonly Modbus_Variables _modbusVars = Modbus_Variables.Instance; public void Store_Recieved_Bytes(byte[] Recieved_Bytes) { _modbusVars.Function_Code = Recieved_Bytes[7]; } } // Server_Socket类中 public class Server_Socket { private readonly Modbus_Variables _modbusVars = Modbus_Variables.Instance; private async void TakeCareOfTCPClient(TcpClient paramClient) { await stream.WriteAsync(Data_Of_Header_File, _modbusVars.Function_Code, 11); } }
2. 依赖注入(复杂项目首选,解耦性强)
如果项目使用依赖注入框架(如ASP.NET Core内置DI),可将Modbus_Variables注册为单例服务,再在需要的类中注入:
// 注册服务(例如Program.cs中) builder.Services.AddSingleton<Modbus_Variables>(); // Modbus类通过构造函数注入 public class Modbus { private readonly Modbus_Variables _modbusVars; public Modbus(Modbus_Variables modbusVars) { _modbusVars = modbusVars; } public void Store_Recieved_Bytes(byte[] Recieved_Bytes) { _modbusVars.Function_Code = Recieved_Bytes[7]; } } // Server_Socket类同样通过构造函数注入 public class Server_Socket { private readonly Modbus_Variables _modbusVars; public Server_Socket(Modbus_Variables modbusVars) { _modbusVars = modbusVars; } private async void TakeCareOfTCPClient(TcpClient paramClient) { await stream.WriteAsync(Data_Of_Header_File, _modbusVars.Function_Code, 11); } }
3. 构造函数/方法传递实例(轻量级解耦)
若不想用单例或DI,可在创建Server_Socket实例时,将Modbus类中的Modbus_Variables实例传递过去:
// Modbus类中暴露实例 public class Modbus { public Modbus_Variables ModBus_Variable { get; } = new Modbus_Variables(); public void Store_Recieved_Bytes(byte[] Recieved_Bytes) { ModBus_Variable.Function_Code = Recieved_Bytes[7]; } } // 创建Server_Socket时传入实例 var modbus = new Modbus(); var serverSocket = new Server_Socket(modbus.ModBus_Variable); // Server_Socket类修改构造函数接收实例 public class Server_Socket { private readonly Modbus_Variables _modbusVars; public Server_Socket(Modbus_Variables modbusVars) { _modbusVars = modbusVars; } private async void TakeCareOfTCPClient(TcpClient paramClient) { await stream.WriteAsync(Data_Of_Header_File, _modbusVars.Function_Code, 11); } }
4. 静态类(注意线程安全)
如果变量无需实例化,可直接用静态类存储,但要处理多线程读写的线程安全问题:
public static class Modbus_Variables { private static readonly object _lockObj = new object(); private static byte _functionCode; public static byte Function_Code { get { lock (_lockObj) { return _functionCode; } } set { lock (_lockObj) { _functionCode = value; } } } }
使用时直接调用静态属性:
// Modbus类中 Modbus_Variables.Function_Code = Recieved_Bytes[7]; // Server_Socket类中 await stream.WriteAsync(Data_Of_Header_File, Modbus_Variables.Function_Code, 11);
注意事项
- 单例和静态类必须关注线程安全:多线程同时读写时,需加锁或使用
Interlocked等线程安全操作。 - 依赖注入适合中大型项目,能提升代码解耦度,便于单元测试。
- 构造函数传递方式灵活性最高,适合小型项目或模块化场景。
内容的提问来源于stack exchange,提问作者shayan ghezelbash
相关产品推荐
相关产品推荐

