2013-03-09 112 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 

`