C# 根据基类和属性顺序对属性进行排序

C# 根据基类和属性顺序对属性进行排序,c#,asp.net,C#,Asp.net,我正在努力完成这件事 public class BaseClass { public int baseint { get; set; } } public class Dervied : BaseClass { public int Derviedint { get; set; } } public class DemoClass : Dervied { [Test(order=2)] public int Demoint { get; set; }

我正在努力完成这件事

public class BaseClass
{
    public int baseint { get; set; }
}

public class Dervied : BaseClass
{
    public int Derviedint { get; set; }
}

public class DemoClass : Dervied
{
    [Test(order=2)]
    public int Demoint { get; set; }

    [Test(order=1)]
    public string Demostring { get; set; }
}
现在我想要一个按排序顺序排列的属性列表,如
List sorted=List()
。现在这个列表应该包含 以下

  • 贝辛特
  • 德维力
  • 演示字符串
  • 妖魔
List info=o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList()

这是给我的财产清单。但这不是我想要的。 这是一个在运行时发送的对象。
非常感谢您的帮助。

这是一个有点扩展的示例-如果需要,您可以将其浓缩成一些,但在这种形式下,更容易看到发生了什么

var o = new DemoClass();
var properties = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
var propertiesWithAttributes = 
    properties.Select(property => 
        new
        {
            Property = property,
            Attribute = property.GetCustomAttributes<TestAttribute>().FirstOrDefault()
        });
var sorted =
    propertiesWithAttributes
    .OrderBy(pwa => pwa.Attribute != null ? pwa.Attribute.order : int.MaxValue);
var o=new DemoClass();
var properties=o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
var propertiesWithAttributes=
属性。选择(属性=>
新的
{
属性=属性,
Attribute=property.GetCustomAttributes().FirstOrDefault()
});
变量排序=
带有属性的属性
.OrderBy(pwa=>pwa.Attribute!=null?pwa.Attribute.order:int.MaxValue);

这是一个略为扩展的示例-如果需要,您可以将其压缩成一些,但在这种形式下,更容易看到发生了什么

var o = new DemoClass();
var properties = o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
var propertiesWithAttributes = 
    properties.Select(property => 
        new
        {
            Property = property,
            Attribute = property.GetCustomAttributes<TestAttribute>().FirstOrDefault()
        });
var sorted =
    propertiesWithAttributes
    .OrderBy(pwa => pwa.Attribute != null ? pwa.Attribute.order : int.MaxValue);
var o=new DemoClass();
var properties=o.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).ToList();
var propertiesWithAttributes=
属性。选择(属性=>
新的
{
属性=属性,
Attribute=property.GetCustomAttributes().FirstOrDefault()
});
变量排序=
带有属性的属性
.OrderBy(pwa=>pwa.Attribute!=null?pwa.Attribute.order:int.MaxValue);

您可以通过在
DemoClass
上爬行
BaseType
的列表,检查
PropertyInfo
DeclaringType
属性,并获取
Test
属性:

void Main()
{
    var t = typeof(DemoClass);
    var typeTree = GetTypeTree(t);
    List<PropertyInfo> info = typeof(DemoClass)
        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
        .OrderByDescending(x => typeTree.IndexOf(x.DeclaringType))
        .ThenBy(GetOrderNumber).ToList();

    foreach (var prop in info)
        Console.WriteLine(prop.Name);
}

int? GetOrderNumber(PropertyInfo prop) {
    var attr = prop.GetCustomAttributes<TestAttribute>(true).FirstOrDefault();
    if (attr != null)
        return attr.order;
    else
        return null;
}

IList<Type> GetTypeTree(Type t) {
    var types = new List<Type>();
    while (t.BaseType != null) {
        types.Add(t);
        t = t.BaseType;
    }
    return types;
}
void Main()
{
var t=类型(DemoClass);
var-typeTree=GetTypeTree(t);
列表信息=类型(DemoClass)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.OrderByDescending(x=>typeTree.IndexOf(x.DeclaringType))
.ThenBy(GetOrderNumber).ToList();
foreach(信息中的var属性)
控制台写入线(道具名称);
}
智力?GetOrderNumber(PropertyInfo属性){
var attr=prop.GetCustomAttributes(true).FirstOrDefault();
如果(attr!=null)
返回属性订单;
其他的
返回null;
}
IList GetTypeTree(类型t){
变量类型=新列表();
while(t.BaseType!=null){
类型。添加(t);
t=t.BaseType;
}
返回类型;
}

您可以使用并按顺序获取每个类的属性,但我认为这种方式更容易理解。

您可以通过在
DemoClass
上爬行
BaseType
的列表,检查
PropertyInfo
DeclaringType
属性,并获取
Test
属性:

void Main()
{
    var t = typeof(DemoClass);
    var typeTree = GetTypeTree(t);
    List<PropertyInfo> info = typeof(DemoClass)
        .GetProperties(BindingFlags.Public | BindingFlags.Instance)
        .OrderByDescending(x => typeTree.IndexOf(x.DeclaringType))
        .ThenBy(GetOrderNumber).ToList();

    foreach (var prop in info)
        Console.WriteLine(prop.Name);
}

int? GetOrderNumber(PropertyInfo prop) {
    var attr = prop.GetCustomAttributes<TestAttribute>(true).FirstOrDefault();
    if (attr != null)
        return attr.order;
    else
        return null;
}

IList<Type> GetTypeTree(Type t) {
    var types = new List<Type>();
    while (t.BaseType != null) {
        types.Add(t);
        t = t.BaseType;
    }
    return types;
}
void Main()
{
var t=类型(DemoClass);
var-typeTree=GetTypeTree(t);
列表信息=类型(DemoClass)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.OrderByDescending(x=>typeTree.IndexOf(x.DeclaringType))
.ThenBy(GetOrderNumber).ToList();
foreach(信息中的var属性)
控制台写入线(道具名称);
}
智力?GetOrderNumber(PropertyInfo属性){
var attr=prop.GetCustomAttributes(true).FirstOrDefault();
如果(attr!=null)
返回属性订单;
其他的
返回null;
}
IList GetTypeTree(类型t){
变量类型=新列表();
while(t.BaseType!=null){
类型。添加(t);
t=t.BaseType;
}
返回类型;
}

您可以按顺序使用并获取每个类的属性,但我认为这种方法更容易理解。

o
。只需使用
typeof(DemoClass)
o
即可获得类型。你只需使用
typeof(DemoClass)
就可以得到这个类型。我认为这符合OP的所有要求。它工作起来很有魅力。如果你在我面前,我会拥抱你。那是凌晨2点左右,仍然在挣扎。终于明白了。真的,你是我今天的英雄。我认为这符合OP的要求。它很有魅力。如果你在我面前,我会拥抱你。那是凌晨2点左右,仍然在挣扎。终于明白了。你真的是我今天的英雄。