GetProperties() 顺序不一致(.NET Core 2 和 .NET Core 3)
GetProperties() order is not consistent (.NET Core 2 & .NET Core 3)
我使用反射来获取 class 的 属性 列表。我需要以与代码中声明的顺序完全相同的顺序获取名称。
当我只调用 typeof(TypeOfClass).GetProperties()
时,我得到了有序的属性。
我的项目中添加的一些代码产生了一些反射读取,阻碍了我的构建。
花了一些时间才找到它,但几个小时后,我发现你得到一个 属性 的名字 GetProperty("name")
它可以在进一步调用 [=14 时更改顺序=]
这是重现相同问题的代码(控制台应用程序):
class Program
{
private class SomeClass
{
public int IntProperty { get; set; }
public string StringProperty { get; set; }
public DateTime DateProperty { get; set; }
}
static void Main(string[] args)
{
PropertyInfo[] propertyInfos = typeof(SomeClass).GetProperties();
Console.WriteLine(string.Join(", ",propertyInfos.Select(p => p.Name)));
//Output: IntProperty, StringProperty, DateProperty
}
}
在 GetProperties
之前访问 GetProperty
的相同代码
class Program
{
private class SomeClass
{
public int IntProperty { get; set; }
public string StringProperty { get; set; }
public DateTime DateProperty { get; set; }
}
static void Main(string[] args)
{
PropertyInfo dateProp = typeof(SomeClass).GetProperty("DateProperty");
PropertyInfo[] propertyInfos = typeof(SomeClass).GetProperties();
Console.WriteLine(string.Join(", ",propertyInfos.Select(p => p.Name)));
//Output: DateProperty, IntProperty, StringProperty
}
}
如果执行第二个代码块,它将return以DateProperty作为第一个索引的属性!?
有谁知道为什么,有没有办法确保 GetProperties 总是return相同顺序的相同列表?
PS:我只在 .netcore 3.1 上尝试过。我认为这可能不是以前版本中的错误。
谢谢
简答:你不能。 As stated in the documentation:
The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies.
返回属性的顺序被视为实现细节,您不能依赖该顺序。
要确定属性在源代码中的定义顺序,您需要访问源代码。
您可以使用CallerLineNumberAttribute Class 它允许您获取调用该方法的源文件中的行号。只有在这种情况下,您才能确定属性的顺序。这对我有用:
private class SomeClass
{
[Order]
public int IntProperty { get; set; }
[Order]
public string StringProperty { get; set; }
[Order]
public DateTime DateProperty { get; set; }
}
这将使编译器将顺序插入到您的属性中:
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class OrderAttribute : Attribute
{
private readonly int order_;
public OrderAttribute([CallerLineNumber]int order = 0)
{
order_ = order;
}
public int Order { get { return order_; } }
}
PropertyInfo dateProp = typeof(SomeClass).GetProperty("DateProperty");
var propertyInfos = from property in typeof(SomeClass).GetProperties()
where Attribute.IsDefined(property,
typeof(OrderAttribute))
orderby ((OrderAttribute)property
.GetCustomAttributes(typeof(OrderAttribute), false)
.Single()).Order
select property;
Console.WriteLine(string.Join(", ", propertyInfos.Select(p => p.Name)));
我使用反射来获取 class 的 属性 列表。我需要以与代码中声明的顺序完全相同的顺序获取名称。
当我只调用 typeof(TypeOfClass).GetProperties()
时,我得到了有序的属性。
我的项目中添加的一些代码产生了一些反射读取,阻碍了我的构建。
花了一些时间才找到它,但几个小时后,我发现你得到一个 属性 的名字 GetProperty("name")
它可以在进一步调用 [=14 时更改顺序=]
这是重现相同问题的代码(控制台应用程序):
class Program
{
private class SomeClass
{
public int IntProperty { get; set; }
public string StringProperty { get; set; }
public DateTime DateProperty { get; set; }
}
static void Main(string[] args)
{
PropertyInfo[] propertyInfos = typeof(SomeClass).GetProperties();
Console.WriteLine(string.Join(", ",propertyInfos.Select(p => p.Name)));
//Output: IntProperty, StringProperty, DateProperty
}
}
在 GetProperties
GetProperty
的相同代码
class Program
{
private class SomeClass
{
public int IntProperty { get; set; }
public string StringProperty { get; set; }
public DateTime DateProperty { get; set; }
}
static void Main(string[] args)
{
PropertyInfo dateProp = typeof(SomeClass).GetProperty("DateProperty");
PropertyInfo[] propertyInfos = typeof(SomeClass).GetProperties();
Console.WriteLine(string.Join(", ",propertyInfos.Select(p => p.Name)));
//Output: DateProperty, IntProperty, StringProperty
}
}
如果执行第二个代码块,它将return以DateProperty作为第一个索引的属性!?
有谁知道为什么,有没有办法确保 GetProperties 总是return相同顺序的相同列表?
PS:我只在 .netcore 3.1 上尝试过。我认为这可能不是以前版本中的错误。
谢谢
简答:你不能。 As stated in the documentation:
The GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies.
返回属性的顺序被视为实现细节,您不能依赖该顺序。
要确定属性在源代码中的定义顺序,您需要访问源代码。
您可以使用CallerLineNumberAttribute Class 它允许您获取调用该方法的源文件中的行号。只有在这种情况下,您才能确定属性的顺序。这对我有用:
private class SomeClass
{
[Order]
public int IntProperty { get; set; }
[Order]
public string StringProperty { get; set; }
[Order]
public DateTime DateProperty { get; set; }
}
这将使编译器将顺序插入到您的属性中:
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public sealed class OrderAttribute : Attribute
{
private readonly int order_;
public OrderAttribute([CallerLineNumber]int order = 0)
{
order_ = order;
}
public int Order { get { return order_; } }
}
PropertyInfo dateProp = typeof(SomeClass).GetProperty("DateProperty");
var propertyInfos = from property in typeof(SomeClass).GetProperties()
where Attribute.IsDefined(property,
typeof(OrderAttribute))
orderby ((OrderAttribute)property
.GetCustomAttributes(typeof(OrderAttribute), false)
.Single()).Order
select property;
Console.WriteLine(string.Join(", ", propertyInfos.Select(p => p.Name)));