C#属性数组

时间:2013-03-09 23:19:09

标签: c# arrays properties getter

我有几个get属性,我希望能够像一组函数一样循环。我希望能够做到这样的事情

public int prop1 { get; }
public string prop2 { get; }
public int[] prop3 { get; }
public int prop4 { get; }
public string prop5 { get; }
public string prop6 { get; }

Func<var> myProperties = { prop1, prop2, prop3, prop4, prop5, prop6 };

ArrayList myList = new ArrayList();
foreach( var p in myProperties)
{
    myList.Add(p);
}

这段代码非常破碎,但我认为它传达了我希望能够做到的想法。有谁知道我怎么能做到这一点?

6 个答案:

答案 0 :(得分:3)

您可以使用反射来访问类型中的属性:

class MyType
{
    public int prop1 { get; }
    public string prop2 { get; }
    public int[] prop3 { get; }
    public int prop4 { get; }
    public string prop5 { get; }
    public string prop6 { get; }

    public List<string> GetAllPropertyValues()
    {
        List<string> values = new List<string>();
        foreach (var pi in typeof(MyType).GetProperties())
        {
            values.Add(pi.GetValue(this, null).ToString());
        }

        return values;
    }
}

请注意,反射很慢,如果有更好的方法,则不应使用此方法。例如,当您知道只有6个属性时,请单独浏览它们。

答案 1 :(得分:0)

您可以尝试使用GetProperties

GetProperties Documentation

示例:

PropertyInfo[] myPropertyInfo;
// Get the properties of 'Type' class object.
myPropertyInfo = Type.GetType("System.Type").GetProperties();
Console.WriteLine("Properties of System.Type are:");
for (int i = 0; i < myPropertyInfo.Length; i++)
{
    Console.WriteLine(myPropertyInfo[i].ToString());
}

进一步信息:
GetProperties with flags的示例非常好,如果您想要访问特定的属性子集(仅限公共场所),它对您有用

答案 2 :(得分:0)

如果您已经知道要循环的所有属性,那么您可以试试这个

List<Reflection.PropertyInfo> myProperties = new List()<object>
{
    typeof(SomeType).GetProperty("prop1"), 
    typeof(SomeType).GetProperty("prop2"), 
    typeof(SomeType).GetProperty("prop3"), 
    typeof(SomeType).GetProperty("prop4"), 
    typeof(SomeType).GetProperty("prop5"), 
    typeof(SomeType).GetProperty("prop6")
};

foreach(var p in myProperties)
{
    var value = p.GetValue(someObject, new object[0]);
    myList.Add(p);
}

如果没有,你可以使用这样的东西:

var myProperties = 
    from pi in someObject.GetType().GetProperties()
    select new 
    {
        pi.Name, 
        Value = pi.GetValue(object, new object[0])
    };

foreach(var p in myProperties)
{
    myList.Add(p.Value);
}

答案 3 :(得分:0)

代码离工作还不远。 myProperties变量应该是一个数组,您需要创建从属性中读取的函数。 (属性getter实际上是作为一个函数实现的,但你不能将它作为函数调用或获取它的引用。)然后你通过调用它们来使用它们。

public class MyClass {

  public int prop1 { get; set; }
  public string prop2 { get; set; }
  public int[] prop3 { get; set; }
  public int prop4 { get; set; }
  public string prop5 { get; set; }
  public string prop6 { get; set; }

  public ArrayList GetProperties() {

    Func<object>[] myProperties = {
      () => prop1, () => prop2, () => prop3,
      () => prop4, () => prop5, () => prop6
    };

    ArrayList myList = new ArrayList();
    foreach (var p in myProperties) {
      myList.Add(p());
    }

    return myList;
  }

}

答案 4 :(得分:0)

如果您需要在数组中使用属性,因为您需要(如我所做)设置和/或获取多个相关(和相同类型)属性,这是您可以执行的操作。我知道反射是“慢'”,但对于我的使用案例,由于反射,重复代码(因此错误机会)减少的好处远远超过任何“慢”(这是无关紧要的)。这不处理索引属性,但可以从中轻松创建一个版本。

` 公共类MyClass {

    private string[] myBoolPropertyNames = 
    {
        nameof(MyBool1Property),
        nameof(MyBool2Property)
    }; // MyBoolPropertyNames =

    private MyClass()
    {
        foreach (var propertyName in myBoolPropertyNames)
        {

            ReflectionHelper.SetPropertyValue
            (
                parentObject: this,
                propertyName: propertyName,
                untypedPropertyValue: true
            ); // SetPropertyValue

        } // foreach (var propertyName in myBoolPropertyNames)

        foreach (var propertyName in myBoolPropertyNames)
        {

            bool boolPropertyValue = ReflectionHelper.GetPropertyValue<bool>
            (
                parentObject: this,
                propertyName: propertyName
            ); // SetPropertyValue

            Console.WriteLine($"Property '{propertyName}' value: {boolPropertyValue}");

        } // foreach (var propertyName in myBoolPropertyNames)
    }

    public bool MyBool1Property { get; set; }
    public bool MyBool2Property { get; set; }

} // MyClass

`

`     公共类ReflectionHelper     {

    public static PropertyType GetPropertyValue<PropertyType>
    (
        object parentObject,
        string propertyName
    )
    {
        if (parentObject == null)
        {
            throw new ArgumentException
            (
                $"Missing '{nameof(parentObject)}'."
            );
        } // if (parentObject == null)

        PropertyInfo propertyInfo = parentObject.GetType().GetProperty(propertyName);
        if (propertyInfo == null)
        {
            throw new ArgumentException
            (
                "No PropertyInfo found for Property: " + propertyName
            );
        } // if (propertyInfo == null)

        object untypedPropertyValue = propertyInfo.GetValue(obj: parentObject);

        Type propertyType = 
        (
            Nullable.GetUnderlyingType(propertyInfo.PropertyType) 
            ?? propertyInfo.PropertyType
        ); // propertyType = 

        object typedPropertyValue = 
        (
            (untypedPropertyValue == null) 
            ? null 
            : Convert.ChangeType(untypedPropertyValue, propertyType)
        ); // typedPropertyValue = 

        return (PropertyType)typedPropertyValue;

    } // GetPropertyValue

    public static void SetPropertyValue
    (
        object parentObject,
        string propertyName,
        object untypedPropertyValue
    )
    {
        if (parentObject == null)
        {
            throw new ArgumentException
            (
                $"Missing '{nameof(parentObject)}'."
            );
        } // if (parentObject == null)

        PropertyInfo propertyInfo = parentObject.GetType().GetProperty(propertyName);
        if (propertyInfo == null)
        {
            throw new ArgumentException
            (
                "No PropertyInfo found for Property: " + propertyName
            );
        } // if (propertyInfo == null)

        Type propertyType = 
        (
            Nullable.GetUnderlyingType(propertyInfo.PropertyType) 
            ?? propertyInfo.PropertyType
        ); // propertyType = 

        object typedPropertyValue =
        (
            (untypedPropertyValue == null)
            ? null
            : Convert.ChangeType(untypedPropertyValue, propertyType)
        ); // typedPropertyValue = 

        propertyInfo.SetValue
        (
            obj: parentObject, 
            value: typedPropertyValue
        ); // propertyInfo.SetValue

    } // SetPropertyValue

} // ReflectionHelper

`

答案 5 :(得分:0)

您可以使用数组缓冲区并从中获取所有支持。通过这种方式,您可以非常快速地获取和设置:

public object[] buf = new object[5];
public int prop1 { get => buf[0]; }
public string prop2 { get => buf[1]; }
public int[] prop3 { get => buf[2]; }
public int prop4 { get => buf[3]; }
public string prop5 { get => buf[4]; }
public string prop6 { get => buf[5]; }

现在可以使用buf访问所有道具:

foreach (var item in buf) {
  myList.Add(item);
}

或直接访问:

buf[1] = 10;
x = buf[1];