我有一个类似于的类(class):

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-在其中声明该属性的位置(在哪个类中):
// 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();

  ...
}

关于c# - 如何以特定顺序获取类中的属性名称列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43893325/

10-13 08:27