2

I have several get properties that I would like to be able to loop through like an array of functions. I would like to be able to do something like this

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

This code is very broken, but I think it conveys the idea of what I would like to be able to do. Anyone know how I can achieve this?

4

6 回答 6

6

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

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 个属性时,只需逐个浏览它们。

于 2013-03-09T23:30:50.220 回答
0

你可以尝试使用GetProperties

GetProperties 文档

例子:

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
示例非常好,如果您想访问特定的属性子集(仅像公共属性),它对您很有用

于 2013-03-09T23:25:05.620 回答
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);
}
于 2013-03-09T23:25:21.733 回答
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;
  }

}
于 2013-03-09T23:36:39.510 回答
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];
于 2019-05-16T14:17:05.733 回答
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

`

于 2017-05-23T05:57:26.757 回答