有没有一种方法可以引用类';s的属性按索引而不是按名称

本文关键字:属性 索引 一种 方法 引用 有没有 | 更新日期: 2023-09-27 18:26:38

假设我有一个这样的类:

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,它定义了相同的类,它通过串行(带有/n个字符,这样我就可以使用SerialPort.ReadLine())将每个prop值作为字符串一次一个地发送给我。当每个值到达时,我想将其放在下一个属性中。我真的很想做这样的事情:

<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等)。

有办法做到这一点吗?

Dave

有没有一种方法可以引用类';s的属性按索引而不是按名称

您可以使用以下内容。。。

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());
}

我能想到几个解决方案,每个方案都有自己的优缺点(没有特定的顺序)

  1. 使用几个数组来存储变量,使用一个类型数组来知道将得到的第n个结果放在哪里。

  2. 使用反射获取所有相关属性并对其进行修改。但是——把它们拿一次并储存起来,不要每次都拿。不要依赖订单(http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx)-创建您自己的订单属性并标记您的属性。因此,当你有一个你选择的订单时,当你重命名或删除一个属性时(或者当MS将更改.net时),它不会改变。

  3. 使用对象数组来存储数据,但使用正确的类型解析每个from字符串。然后,您可以让您的属性包装数组。

    公共字节ALS

    获取

    return(byte)m_properties[ALS_INDEX]
    }
    设置

    m_properties[ALS_INDEX]=值
    }
    }

您可以使用反射来迭代属性,这不会给您提供索引访问,但我认为属性是按确定的顺序返回的。

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));
}