我有一个类似于的类:
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; }
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个从类中提取名称的方法.
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....
}
Run Code Online (Sandbox Code Playgroud)
所以,当我得到我的数组时,它将按以下顺序:
Field1
Field2
Field3
Field4
BaseField1
BaseField2
BaseField3
BaseField4
Run Code Online (Sandbox Code Playgroud)
我想知道是否可以更改顺序,以便基类字段首先跟随派生类字段?
让我们实现一个简单的方法来获得类层次结构中类的深度
null <- object <- ... <- MyBaseClass <- MyClass <- ...
Run Code Online (Sandbox Code Playgroud)
履行
// 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;
}
Run Code Online (Sandbox Code Playgroud)
然后在这个标准的Linq帮助下,唯一的小技巧是使用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));
Run Code Online (Sandbox Code Playgroud)
结果:
BaseField1
BaseField2
BaseField3
BaseField4
Field1
Field2
Field3
Field4
Run Code Online (Sandbox Code Playgroud)
最后,您的方法可以是这样的:
// 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();
...
}
Run Code Online (Sandbox Code Playgroud)