获得一个类的第n个属性

时间:2014-06-27 11:09:23

标签: c# asp.net

是C#语言的初学者

我有一个像

这样的课程
public  class Plan
{
       int a;
       int b;
       int c;     
}  

我可以以任何方式获得该类的第n个属性。

例如:planObject.propertyIndex

这对我的项目有很大帮助,因为我得到的索引号表示要更改其值的属性。我现在正在做的是使用if ...... else。

   if(index ==1)
   {
         planObject.a = 100;
   }
   else if(index ==2)    
   {
      planObject.b = 100;
   }

使用反射是否有其他解决方案?

5 个答案:

答案 0 :(得分:2)

可以使用反射,但是,我强烈建议反对。而是使用像List<int>int[]这样的集合。在这种情况下,由于您希望获得第n个 int值,因此您还可以使用Dictionary<int, int>

public  class Plan
{
    Dictionary<int, int> Values;

    public Plan()
    {
        Values = new Dictionary<int, int>();
        Values.Add(1, 100);
        Values.Add(2, 200);
        Values.Add(3, 300);
    }

    // ...
}

现在您可以通过数字访问该值:

int value = Values[1]; // 100 

这是一个列表版本:

public  class Plan
{
    List<int> Values = new List<int>();

    public Plan()
    {
        Values.Add(100);
        Values.Add(200);
        Values.Add(300);
    }

    // ...
}

您可以通过(基于零)索引访问它:

int value = Values[0]; // 100 

答案 1 :(得分:1)

没有“依据索引的属性”功能,但是一种使消费更容易的方法是在类上构建索引器并在那里封装switch语句。也许是这样的:

public class Plan
{
    public int this[int index]
    {
        get
        {
            switch (index)
            {
                case 1:
                    return this.a;
                ...
            }
        }
        set
        {
            switch (index)
            {
                case 1:
                    this.a = value;
                ...
            }
        }
    }
}

所以,现在使用它看起来像这样:

planObject[i] = 100;

现在,在您的情况下,看起来像您需要额外的需求,因为您有(索引)和(例如100),因此您需要将密钥和值存储在Dictionary中。因此,在使用Plan的班级中创建private field

private Dictionary<int, int> _values = new Dictionary<int, int>
{
    { 1, 100 },
    { 2, 200 },
    ...
}

要使用字典,您可以执行以下操作:

planObject[i] = _values[i];

更新:如果您无法更改班级Plan,那么您需要执行此类操作。首先,您需要从索引到属性名称的映射:

private Dictionary<int, string> _properties = new Dictionary<int, string>
{
    { 1, "a" },
    { 2, "b" },
    ...
}

接下来你需要设置该属性:

var t = planObject.GetType();
var p = t.GetProperty(_properties[i]);
if (p != null)
{
    p.SetValue(planObject, 100);
}

答案 2 :(得分:1)

如果您必须使用该对象,而不是建议的集合。

Plan b = new Plan();
Type t = new Type(b.GetType());
var properties = t.GetProperties();
for(int index = 0; index < properties.Length; index++)
{
    properties[index].SetValue(b, 100);  
}

您可以在properties数组中传递自己的索引,而不是使用循环。 我希望它有所帮助。

答案 3 :(得分:1)

一句话警告,这根本不适合初学者。它可能只会使代码更复杂。这个答案理所当然地认为你具有扩展方法和反思的工作知识。

public static class PlanExtension
{
  PropertyInfo _info = typeof(Plan).GetProperties();

  public static void SetValue(this Plan plan, int index, int value)
  {
    var prop = _info[index - 1]; // So 1 maps to 0.. or 1 in this case
    prop.SetValue(plan, value, null);
  }

  public static int GetValue(this Plan plan, int index)
  {
    var prop = _info[index - 1]; // Mapping magic
    return (int) prop.GetValue(plan, null);
  }
}

这样称呼:

var p = new Plan();
p.SetValue(1, 139); // "a"
var b = p.GetValue(2); // "b"

如果您对属性有可定义的命令,如名称或其他内容,那将会有所帮助。此外,在反思时,错误处理是必须的。

答案 4 :(得分:0)

这是你想要的

public class Foo 
{
    public int A {get;set;}
    public string B {get;set;}
    public object GetPropertyValueAt(int index)
    {
        var prop = this.GetType().GetProperties()[index];
        return prop.GetValue(this, null);
    }
}

用法

Foo foo = new Foo() {A = 1, B = "abc"};
int valueA = (int)foo.GetPropertyValueAt(0);
string valueB = (string)foo.GetPropertyValueAt(1);
int valueUnknown = (int)foo.GetPropertyValueAt(2); //<--- this line will give you an exception.