page contents

C#反射属性顺序

本文讲述了C#反射属性顺序!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2022-08-Bj3QScrv630ebda0487bf.png

本文讲述了C#反射属性顺序!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

我正在使用https://stackoverflow.com/a/531388/528131中的代码从基础成功检索对象实例的所有属性,问题是派生类型的属性首先被迭代。 由于协议的性质,我首先需要基本属性。

1
2
3
4
|
| B
|
| A

B和A是类,B是从A派生的。x,y,z是B的属性,w是A的属性

这是A.GetProperties(); 正在返回。 我需要这个代替:

1
2
3
4
| A
|
| B
|

有什么方法可以准确地按顺序获得字段吗?

 
  • 这回答了你的问题了吗? C#以原始顺序获取FieldInfos / PropertyInfos吗?

类型中的字段不是"有序的"。这些方法中项目的顺序是实现细节,强烈建议不要依赖它们。

您应该自己订购这些项目,并期望它们可以从任何位置开始,以确保您的程序健壮而不是脆弱。

由于可以要求每个属性提供声明它的类型,因此您可以从头开始创建一个查找,该查找为层次结构中的每个类提供一个编号,从您开始的类型一直到object,通过遍历BaseType Type的属性,并按每个属性的声明类型的查找值进行排序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static IEnumerable<PropertyInfo> GetOrderedProperties(Type type)
{
    Dictionary<Type, int> lookup = new Dictionary<Type, int>();

    int count = 0;
    lookup[type] = count++;
    Type parent = type.BaseType;
    while (parent != null)
    {
        lookup[parent] = count;
        count++;
        parent = parent.BaseType;
    }

    return type.GetProperties()
        .OrderByDescending(prop => lookup[prop.DeclaringType]);
}
 
  • ID必须能够在分层阶梯中将this"切片"为基本类型和派生类型,并向每个切片询问THEIR属性,而不是派生类型或基本类型属性。有任何想法吗?
  • 这似乎是更简单的方法。真好!当我进行更多测试时,我会将其标记为答案。

反射子系统的文档说,您不能依赖于元素返回的顺序。

也就是说,根据我的经验,在源文件中按声明顺序返回元素是我的经验。在Mono或.NET的将来版本中,这可能是正确的,也可能不是。

尽管如此,如果您希望继续进行操作,最好的选择是使用BindingFlags.DeclaredOnly选项并手动遍历继承层次结构(在子类型之前扫描基本类型以使其顺序正确)。您应该以这样一种方式编写代码,即从单个声明的类型开始的属性排序无关紧要(例如,按名称对它们进行排序);如果.NET框架的行为发生变化,这将使您的代码更加健壮。

Fasterflect这样做(主要是为了能够滤除已被覆盖的虚拟属性)。它还具有帮助程序,可以使用其自己的功能更强大的Flags选择器参数来获取是否经过过滤的属性。

如果单个类型中元素的顺序并不重要,则可以使用以下方法获得列表(使用Fasterflect):

1
var properties = type.Properties().Reverse().ToList();

您应注意,以这种方式反映时(通过遍历并仅获取声明的属性)将多次包含重写的属性。 Fasterflect提供了从结果中过滤掉这些的选项:

1
var properties = type.Properties( Flags.InstancePublic | Flags.ExcludeBackingMembers ).Reverse().ToList();

如果您不希望依赖库,那么该代码是开源的,因此您可以选择所需的位。遍历算法可以在此处看到(第443行)。

 
  • +1。这将允许按问题中指定的顺序选择属性(需要递归遍历所有基类以按所需顺序获取完整列表)
  • 我还假定属性总是按声明的顺序进行,因为当我手动执行代码时,它们似乎总是如此。我整天开始运行单元测试后,由于在属性上使用int索引,它们很快就开始随机失败。在大多数情况下,它们是声明的,但有时并非如此!当文档说"不保证"时,它们是真的!我不得不放弃我的假设并使用名称索引重新实现。

您要做的就是通过声明类型分组并反转列表

1
2
3
4
5
 var publicProperties = typeof(T).GetProperties()
                .GroupBy(=> p.DeclaringType)
                .Reverse()
                .SelectMany(=> g)
                .ToArray();

作为另一种排序方法:

1
2
3
4
5
6
7
8
9
10
PropertyInfo[] properties = type.GetProperties(...);
Array.Sort(properties, (pi1, pi2) =>
    {
        if (pi1.DeclaringType.IsSubclassOf(pi2.DeclaringType))
           return 1;
        else if  (pi2.DeclaringType.IsSubclassOf(pi1.DeclaringType))
            return -1;
        else
            return 0;
    });

您可以从PropertyInfo实例获取声明类型,并按其与object的距离进行排序。

这就是我要做的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void Main()
{
    typeof(B).GetProperties()
    .Select((x,i) => new {
        Prop = x,
        DeclareOrder = i,
        InheritanceOrder = GetDepth(x.DeclaringType),
    })
    .OrderByDescending(=> x.InheritanceOrder)
    .ThenBy(=> x.DeclareOrder)
    .Dump();
}

public class A
{
    public string W {get; set;}
}

public class B : A
{
    public string X {get; set;}
    public string Y {get; set;}
    public string Z {get; set;}
}

static int GetDepth(Type t)
{
    int depth = 0;
    while (!= null)
    {
        depth++;
        t = t.BaseType;
    }
    return depth;
}
  • 如果您不需要声明该getdepth方法,我想更多。
  • OrderBy进行稳定的排序,而不是不稳定的排序,因此保持了相等项的顺序。因此,不需要ThenBy,也不需要选择。您唯一需要的是typeof(B).GetProperties().OrderBy(prop => GetDepth(prop)),它的优点是只返回属性,因为我们可能不关心排序后的深度。您可能应该有一个额外的Select,以根据您的情况获取该属性。请注意,这种方法或多或少与我在答案中所做的相同,只是我预先计算了深度并对其进行了缓存以避免重复。
  • @caesay好吧,您不会说,但是最肯定的是使用该方法会更好。您为什么反对创建辅助方法?
  • 此技术无法正常使用继承。它将我的基类属性放在列表的末尾。


更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2022-08-31 09:47
  • 阅读 ( 434 )
  • 分类:C/C++开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1320 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章