C#属性数组

我有几个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 myProperties = { prop1, prop2, prop3, prop4, prop5, prop6 }; ArrayList myList = new ArrayList(); foreach( var p in myProperties) { myList.Add(p); } 

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

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

 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 GetAllPropertyValues() { List values = new List(); foreach (var pi in typeof(MyType).GetProperties()) { values.Add(pi.GetValue(this, null).ToString()); } return values; } } 

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

您可以尝试使用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示例非常好,如果您想要访问特定的属性子集(仅限公共场所),它对您很有用。

代码离工作还不远。 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[] myProperties = { () => prop1, () => prop2, () => prop3, () => prop4, () => prop5, () => prop6 }; ArrayList myList = new ArrayList(); foreach (var p in myProperties) { myList.Add(p()); } return myList; } } 

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

 List myProperties = new List() { 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); } 

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

`public class 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 ( 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 

`

`public class ReflectionHelper {

  public static PropertyType GetPropertyValue ( 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 

`