假设我有一个这样的课程:
public class Config {
public byte ALS { get; set; }
public bool BCP { get; set; }
public short NRG { get; set; }
// 46 more bytes, shorts, and bools
public byte GRT { get; set; }
}
Config myConfig = new Config();
现在假设我有一个Arduino,它定义了相同的类,并且它将每个prop值作为一个字符串一次一个地以相同的顺序通过串行发送给我(使用/ n个字符,所以我可以使用SerialPort.ReadLine( ))。当每个值到来时,我想把它放在下一个属性中。我真的想做这样的事情:
<psudo code>
for (int i = 0; i < 50; i++)
{
myConfig[i] = (Config[i].GetType())port.ReadLine(); //reference the property by index, not by name
}
</psudo code>
注意我在将新到达的值转换为适合目标属性类型之后,将每个新到达值放在我的实例的下一个属性中。我不是通过名称(ALS,BCP,NRG等)指定下一个属性,而是通过索引(0,1,2,3等)指定。
有办法做到这一点吗?
戴夫
答案 0 :(得分:2)
我可以想到几个解决方案,每个解决方案都有其优点和缺点(没有特别的顺序)
使用多个数组来存储变量和一组类型,以便知道将第n个结果放到哪里。
使用反射获取所有相关属性并进行修改。但是 - 得到它们一次并存储它们,不要每次都得到它们。并且不依赖于订单(http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx) - 创建自己的订单属性并标记您的属性。因此,当您重新命名或删除某个属性时(或当MS将更改.net)时,您将获得所选择的订单不会更改。
使用对象数组存储数据,但使用正确的类型从字符串中解析每个数据。然后,您可以将属性包装在数组中。
公共字节ALS
{
得到
{
return(byte)m_properties [ALS_INDEX];
}
设置
{
m_properties [ALS_INDEX] =值;
}
}
答案 1 :(得分:0)
您可以使用反射来迭代属性,这不会为您提供索引访问,但我认为属性是以确定的顺序返回的。
Type type = obj.GetType();
BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
PropertyInfo[] properties = type.GetProperties(flags);
foreach (PropertyInfo property in properties)
{
Console.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null));
}
答案 2 :(得分:0)
您可以使用以下内容......
public class Config {
[Display(Order=0)]
public byte ALS { get; set; }
[Display(Order=1)]
public bool BCP { get; set; }
[Display(Order=2)]
public short NRG { get; set; }
[Display(Order=3)]
public byte GRT { get; set; }
}
属性Display
来自System.ComponentModel.DataAnnotations
命名空间
现在你可以编写一个扩展方法,如下所示
public static PropertyInfo GetProperty(this Type type, int index)
{
return type.GetProperties().FirstOrDefault(p => ((DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), false)[0]).Order == index);
}
现在您可以使用它并将值分配给对象上的字段,如下所示
Config config = new Config();
for(int i = 0; i < 50; i++)
{
config.GetType().GetProperty(i).SetValue(config, port.ReadLine());
}