1.概要
情景:软硬件间通过modbus协议通过,通讯的接口以通讯表中点位的形式体系,点位分为触发点位和参数点位。交互点位和参数点位组成一个通讯的结构,点位、点位描述、点位值,这些对于一个标准的交互是完全相同的,于是我封装一个通讯实体对象,具有自己初始化通讯点位和取数据的功能,这样应用层就只需要使用处理完的数据做业务处理就好了。
2.代码
using System;
using System.Collections.Generic;
using System.Reflection;
namespace 通讯表数据读成对象实验2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("通讯表数据读成对象实验2");
//构造通讯对象,并绑定通讯基础类
IndexValuesA indexValuesA = new IndexValuesA(new DcsBase());
//获取值
indexValuesA.getValues();
//数据表示
indexValuesA.view();
Console.ReadKey();
}
}
/// <summary>
/// 通讯点位对象类
/// </summary>
/// <typeparam name="T"></typeparam>
class IndexVavlue<T> {
public ushort addrIndex;
public object Value { set; get; }
}
/// <summary>
/// int类型点位
/// </summary>
class IndexInt: IndexVavlue<int>
{
}
/// <summary>
/// 字符类型点位
/// </summary>
class IndexString: IndexVavlue<string>
{
}
/// <summary>
/// 通讯基础模拟类
/// </summary>
class DcsBase {
Dictionary<ushort, string> stings = new Dictionary<ushort, string>();
Dictionary<ushort, int> ints = new Dictionary<ushort, int>();
Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
public DcsBase() {
stings.Add(2, "test");
ints.Add(1, 5);
dictionary.Add("s_gz_11", 1);
dictionary.Add("s_gz_22", 2);
}
public string getString(ushort index) {
return stings[index];
}
public int getInt(ushort index) {
return ints[index];
}
public ushort getIndex(string key) {
return dictionary[key];
}
}
/// <summary>
/// 基类
/// </summary>
class IndexValuesBase {
Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
DcsBase dcsBase;
public IndexValuesBase(DcsBase dcsBase)
{
this.dcsBase = dcsBase;
//初始化的时候生成通讯偏移地址
initAddr();
}
/// <summary>
/// 通讯偏移量获取
/// </summary>
public void initAddr() {
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
IndexAddr indexAddr = propertyInfo.GetCustomAttribute<IndexAddr>();
//如果没有偏移的特性不需要处理
if (indexAddr == null)
{
continue;
}
//获取通讯表中的偏移量
ushort value = dcsBase.getIndex(indexAddr.getKey());
object indexVavlue = this.GetType().Assembly.CreateInstance(propertyInfo.PropertyType.FullName);
FieldInfo fieldInfo = propertyInfo.PropertyType.GetField("addrIndex");
fieldInfo.SetValue(indexVavlue, value);
propertyInfo.SetValue(this, indexVavlue);
}
}
/// <summary>
/// 获取从通讯层取得的值
/// </summary>
public void getValues() {
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
IndexAddr indexAddr = propertyInfo.GetCustomAttribute<IndexAddr>();
//如果没有偏移的特性不需要处理
if (indexAddr == null)
{
continue;
}
//获取通讯表中的偏移量
ushort value = dcsBase.getIndex(indexAddr.getKey());
if (propertyInfo.PropertyType == typeof(IndexVavlue<int>))
{
IndexVavlue<int> indexVavlue = (IndexVavlue<int>)propertyInfo.GetValue(this);
indexVavlue.Value = dcsBase.getInt(indexVavlue.addrIndex);
}
else if (propertyInfo.PropertyType == typeof(IndexVavlue<string>))
{
IndexVavlue<string> indexVavlue = (IndexVavlue<string>)propertyInfo.GetValue(this);
indexVavlue.Value = dcsBase.getString(indexVavlue.addrIndex);
}
}
}
delegate void fun1(string n,object o);
/// <summary>
/// 数据表示
/// </summary>
public void view() {
fun1 f = (string n,object v) =>
{
Console.WriteLine(n + ":" + v.ToString());
};
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
object o = propertyInfo.GetValue(this);
FieldInfo[] fieldInfos = o.GetType().GetFields();
foreach (FieldInfo fieldInfo in fieldInfos) {
f(fieldInfo.Name, fieldInfo.GetValue(o));
}
PropertyInfo[] propertyInfos1 = o.GetType().GetProperties();
foreach (PropertyInfo propertyInfo1 in propertyInfos1) {
f(propertyInfo1.Name, propertyInfo1.GetValue(o));
}
}
}
}
/// <summary>
/// 举例
/// </summary>
class IndexValuesA: IndexValuesBase
{
public IndexValuesA(DcsBase dcsBase) : base(dcsBase) {
//a = new IndexVavlue<int>();
//b = new IndexVavlue<string>();
}
[IndexAddr("s", "gz", "11")]
public IndexVavlue<int> a { set; get; }
[IndexAddr("s", "gz", "22")]
public IndexVavlue<string> b { set; get; }
}
/// <summary>
/// 用于表示偏移两对应的key
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public class IndexAddr : Attribute
{
public IndexAddr(string indexType, string indexStation, string key)
{
this.indexType = indexType;
this.indexStation = indexStation;
this.indexKey = key;
}
public string indexKey;//key
public string indexType;//R orS
public string indexStation;//工位地址
public string getKey()
{
return indexType + "_" + indexStation + "_" + indexKey;
}
}
}
3.运行结果
通讯表数据读成对象实验2
addrIndex:1
Value:5
addrIndex:2
Value:test
4.历史版本
4.1第一版
using System;
using System.Collections.Generic;
using System.Reflection;
namespace 通讯表数据读成对象实验2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("通讯表数据读成对象实验2");
IndexValuesA indexValuesA = new IndexValuesA(new DcsBase());
indexValuesA.initAddr();
indexValuesA.getValues();
Console.ReadKey();
}
}
class IndexVavlue<T> {
public ushort addrIndex;
public object Value { set; get; }
}
class IndexInt: IndexVavlue<int>
{
}
class IndexString: IndexVavlue<string>
{
}
class DcsBase {
Dictionary<ushort, string> stings = new Dictionary<ushort, string>();
Dictionary<ushort, int> ints = new Dictionary<ushort, int>();
Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
public DcsBase() {
stings.Add(2, "test");
ints.Add(1, 5);
dictionary.Add("s_gz_11", 1);
dictionary.Add("s_gz_22", 2);
}
public string getString(ushort index) {
return stings[index];
}
public int getInt(ushort index) {
return ints[index];
}
public ushort getIndex(string key) {
return dictionary[key];
}
}
class IndexValuesBase {
Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
DcsBase dcsBase;
public IndexValuesBase(DcsBase dcsBase)
{
this.dcsBase = dcsBase;
}
public void initAddr() {
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
IndexAddr indexAddr = propertyInfo.GetCustomAttribute<IndexAddr>();
//如果没有偏移的特性不需要处理
if (indexAddr == null)
{
continue;
}
//获取通讯表中的偏移量
ushort value = dcsBase.getIndex(indexAddr.getKey());
string typeName = propertyInfo.PropertyType.Name;
if (propertyInfo.PropertyType == typeof(IndexVavlue<int>))
{
IndexVavlue<int> indexVavlue = (IndexVavlue<int>)propertyInfo.GetValue(this);
indexVavlue.addrIndex = value;
}
else if(propertyInfo.PropertyType == typeof(IndexVavlue<string>)) {
IndexVavlue<string> indexVavlue = (IndexVavlue<string>)propertyInfo.GetValue(this);
indexVavlue.addrIndex = value;
}
}
}
public void getValues() {
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
IndexAddr indexAddr = propertyInfo.GetCustomAttribute<IndexAddr>();
//如果没有偏移的特性不需要处理
if (indexAddr == null)
{
continue;
}
//获取通讯表中的偏移量
ushort value = dcsBase.getIndex(indexAddr.getKey());
if (propertyInfo.PropertyType == typeof(IndexVavlue<int>))
{
IndexVavlue<int> indexVavlue = (IndexVavlue<int>)propertyInfo.GetValue(this);
indexVavlue.Value = dcsBase.getInt(indexVavlue.addrIndex);
}
else if (propertyInfo.PropertyType == typeof(IndexVavlue<string>))
{
IndexVavlue<string> indexVavlue = (IndexVavlue<string>)propertyInfo.GetValue(this);
indexVavlue.Value = dcsBase.getString(indexVavlue.addrIndex);
}
}
}
}
class IndexValuesA: IndexValuesBase
{
public IndexValuesA(DcsBase dcsBase) : base(dcsBase) {
a = new IndexVavlue<int>();
b = new IndexVavlue<string>();
}
[IndexAddr("s", "gz", "11")]
public IndexVavlue<int> a { set; get; }
[IndexAddr("s", "gz", "22")]
public IndexVavlue<string> b { set; get; }
}
/// <summary>
/// 用于表示偏移两对应的key
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public class IndexAddr : Attribute
{
public IndexAddr(string indexType, string indexStation, string key)
{
this.indexType = indexType;
this.indexStation = indexStation;
this.indexKey = key;
}
public string indexKey;//key
public string indexType;//R orS
public string indexStation;//工位地址
public string getKey()
{
return indexType + "_" + indexStation + "_" + indexKey;
}
}
}
4.2 第二版
using System;
using System.Collections.Generic;
using System.Reflection;
namespace 通讯表数据读成对象实验2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("通讯表数据读成对象实验2");
IndexValuesA indexValuesA = new IndexValuesA(new DcsBase());
indexValuesA.initAddr();
indexValuesA.getValues();
Console.ReadKey();
}
}
class IndexVavlue<T> {
public ushort addrIndex;
public object Value { set; get; }
}
class IndexInt: IndexVavlue<int>
{
}
class IndexString: IndexVavlue<string>
{
}
class DcsBase {
Dictionary<ushort, string> stings = new Dictionary<ushort, string>();
Dictionary<ushort, int> ints = new Dictionary<ushort, int>();
Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
public DcsBase() {
stings.Add(2, "test");
ints.Add(1, 5);
dictionary.Add("s_gz_11", 1);
dictionary.Add("s_gz_22", 2);
}
public string getString(ushort index) {
return stings[index];
}
public int getInt(ushort index) {
return ints[index];
}
public ushort getIndex(string key) {
return dictionary[key];
}
}
class IndexValuesBase {
Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>();
DcsBase dcsBase;
public IndexValuesBase(DcsBase dcsBase)
{
this.dcsBase = dcsBase;
}
public void initAddr() {
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
IndexAddr indexAddr = propertyInfo.GetCustomAttribute<IndexAddr>();
//如果没有偏移的特性不需要处理
if (indexAddr == null)
{
continue;
}
//获取通讯表中的偏移量
ushort value = dcsBase.getIndex(indexAddr.getKey());
string typeName = propertyInfo.PropertyType.Name;
if (propertyInfo.PropertyType == typeof(IndexVavlue<int>))
{
//IndexVavlue<int> indexVavlue = (IndexVavlue<int>)propertyInfo.GetValue(this);
//indexVavlue.addrIndex = value;
//IndexVavlue<object> indexVavlue = new IndexVavlue<object>();
//indexVavlue.addrIndex = value;
//propertyInfo.SetValue(this, indexVavlue);
IndexVavlue<int> indexVavlue = (IndexVavlue<int>)this.GetType().Assembly.CreateInstance(propertyInfo.PropertyType.FullName);
indexVavlue.addrIndex = value;
propertyInfo.SetValue(this, indexVavlue);
}
else if(propertyInfo.PropertyType == typeof(IndexVavlue<string>)) {
//IndexVavlue<string> indexVavlue = (IndexVavlue<string>)propertyInfo.GetValue(this);
//indexVavlue.addrIndex = value;
IndexVavlue<string> indexVavlue = new IndexVavlue<string>();
indexVavlue.addrIndex = value;
propertyInfo.SetValue(this, indexVavlue);
}
}
}
public void getValues() {
PropertyInfo[] propertyInfos = this.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
IndexAddr indexAddr = propertyInfo.GetCustomAttribute<IndexAddr>();
//如果没有偏移的特性不需要处理
if (indexAddr == null)
{
continue;
}
//获取通讯表中的偏移量
ushort value = dcsBase.getIndex(indexAddr.getKey());
if (propertyInfo.PropertyType == typeof(IndexVavlue<int>))
{
IndexVavlue<int> indexVavlue = (IndexVavlue<int>)propertyInfo.GetValue(this);
indexVavlue.Value = dcsBase.getInt(indexVavlue.addrIndex);
}
else if (propertyInfo.PropertyType == typeof(IndexVavlue<string>))
{
IndexVavlue<string> indexVavlue = (IndexVavlue<string>)propertyInfo.GetValue(this);
indexVavlue.Value = dcsBase.getString(indexVavlue.addrIndex);
}
}
}
}
class IndexValuesA: IndexValuesBase
{
public IndexValuesA(DcsBase dcsBase) : base(dcsBase) {
//a = new IndexVavlue<int>();
//b = new IndexVavlue<string>();
}
[IndexAddr("s", "gz", "11")]
public IndexVavlue<int> a { set; get; }
[IndexAddr("s", "gz", "22")]
public IndexVavlue<string> b { set; get; }
}
/// <summary>
/// 用于表示偏移两对应的key
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public class IndexAddr : Attribute
{
public IndexAddr(string indexType, string indexStation, string key)
{
this.indexType = indexType;
this.indexStation = indexStation;
this.indexKey = key;
}
public string indexKey;//key
public string indexType;//R orS
public string indexStation;//工位地址
public string getKey()
{
return indexType + "_" + indexStation + "_" + indexKey;
}
}
}
该博客介绍了一个针对Modbus协议的通讯实体对象封装,通过属性的特性注解映射通讯点位,实现了从通讯表读取并设置数据的功能。在应用层可以直接使用处理好的数据进行业务处理,简化了通讯过程。

被折叠的 条评论
为什么被折叠?



