2013-03-09 58 views
2

我有几个获取属性,我希望能够循环通过像一个函数数组。我希望能够做这样的事C#数组属性

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

此代码是很破,但我认为它传达的,我想怎样能够做到的想法。任何人都知道我可以做到这一点?

+3

的[文档'Func键'](http://msdn.microsoft.com/en-us/library/bb534960.aspx)向您展示了不少于四种正确创建它们的方法。另外,考虑到代码中有多少内容,您应该花更多时间阅读C#教程。 – millimoose 2013-03-09 23:23:55

+0

如果不使用反射,您将不得不创建一个数据结构(例如'List')来保存对每个属性的引用;然后遍历该数据结构。 – 2013-03-09 23:25:23

回答

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的例子是非常好的,它可以对您有用,如果你想要访问属性的特定子集(仅限公众人士)

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

这只会保存每个属性的值,并且不会反映对属性(或者说支持字段)的更新而不重新加载“List”。 – 2013-03-09 23:26:40

+0

'prop1',...,'prop6'应该是什么? – poke 2013-03-09 23:26:48

+0

@poke我不完全确定你是否想引用属性本身或仅仅是它们的值。我已经更新了我的答案,以解释如何以两种不同的方式获得两者。 – 2013-03-09 23:38:42

2

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

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个属性时,请单独通过它们。

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

} 
0

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

` 公共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 

`