[英]How to get a list of property names in a class in certain a order
我有一個類似於的類:
public class MyClass : MyBaseClass
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
}
public class MyBaseClass
{
public string BaseField1 { get; set; }
public string BaseField2 { get; set; }
public string BaseField3 { get; set; }
public string BaseField4 { get; set; }
}
然后我創建了一個從類中提取名稱的方法。
private void MyMethod<T>(List<T> listData) where T : class
{
String[] fieldNames = Array.ConvertAll<PropertyInfo, String>(typeof(T).GetProperties(), delegate(PropertyInfo fo) { return fo.Name; });
// Do something with the fieldNames array....
}
所以當我得到我的數組時,它將按以下順序:
Field1
Field2
Field3
Field4
BaseField1
BaseField2
BaseField3
BaseField4
我想知道是否可以更改順序,以便基類字段首先跟隨派生類字段?
讓我們實現一個簡單的方法來獲得類層次結構中類的深度
null <- object <- ... <- MyBaseClass <- MyClass <- ...
履行
// 0 - null
// 1 - object
// ...
// n - MyBaseClass
// n + 1 - MyClass
// ...
private static int TypeLevel(Type type) {
if (null == type)
return 0;
return TypeLevel(type.BaseType) + 1;
}
然后在這個標准的Linq幫助下,唯一的小技巧是使用DeclaringType
- DeclaringType
屬性的位置(在哪個類中):
// fieldNames are actually properties' names
string[] fieldNames = typeof(MyClass)
.GetProperties()
.OrderBy(p => TypeLevel(p.DeclaringType)) // <- base first, derived last
.ThenBy(p => p.Name) // <- let's organize properties within each class
.Select(p => p.Name)
.ToArray();
Console.Write(string.Join(Environment.NewLine, fieldNames));
結果:
BaseField1
BaseField2
BaseField3
BaseField4
Field1
Field2
Field3
Field4
最后,您的方法可以是這樣的:
// we don't want any restictions like "where T : class"
private void MyMethod<T>(List<T> listData) {
...
string[] fieldNames = typeof(T)
.GetProperties()
.OrderBy(p => TypeLevel(p.DeclaringType)) // <- base first, derived last
.ThenBy(p => p.Name) // <- let's organize properties within each class
.Select(p => p.Name)
.ToArray();
...
}
您將不得不編寫如下代碼來遍歷類層次結構,然后獲取屬性
static void GetProperties(Type type, List<string> returnValue) {
var props = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
returnValue.AddRange(props.Select(p => p.Name).OrderBy(p => p));
}
private void MyMethod<T>(List<T> listData) where T : class {
var type = typeof(T);
List<string> properties = new List<string>();
while (type != null) {
GetProperties(type, properties);
type = type.BaseType;
}
}
選擇基類的所有屬性,並使用派生類的所有屬性進行聯合。 Distinct()將刪除所有重復項。 如果需要更多復雜性,您將不得不嘗試@Vikhram解決方案。
var properties = typeof(MyBaseClass).GetProperties().Select(x => x.Name)
.Union(typeof(MyClass).GetProperties().Select(x => x.Name)).Distinct();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.