c# - Why are two different instances of the same attribute equal here?
问题描述
I have two classes that are decorated with the same attribute but different values. When I dump them in LINQPad I can see that they are different but when I do x.Equals(y)
then it yields true
even though the implementation of Equals
actually compares property values.
This code reproduces this issue:
void Main()
{
var a1 = typeof(T1).GetCustomAttribute<A2>().Dump();
var a2 = typeof(T3).GetCustomAttribute<A2>().Dump();
a1.Equals(a2).Dump();
}
[A1(V = "I1")]
interface I1
{
[A1(V = "I1.P1")]
string P1 { get; set; }
}
[A2(V = "T1")] // <-- typeof(T1).GetCustomAttribute<A2>()
class T1 : I1
{
[A1(V = "T1.P1")]
public virtual string P1 { get; set; }
}
class T2 : T1 { }
[A1(V = "T3"), A2(V = "T3")] // <-- typeof(T3).GetCustomAttribute<A2>()
class T3 : T2
{
[A1(V = "T3.P1")]
public override string P1 { get; set; }
}
class A1 : Attribute { public string V { get; set; } }
class A2 : A1 { }
And these are the results:
UserQuery+A2 TypeId = typeof(A2) V = T1 UserQuery+A2 TypeId = typeof(A2) V = T3 True // <-- a1.Equals(a2).Dump();
What am I missing here and how can I properly compare them?
解决方案
The A1
attribute class declares an auto-property with a private compiler-generated backing field.
Now, when the Attribute.Equals
method reflects over A2
to access all its instance fields (Attribute.Equals does not reflect over properties), it will not "see" the private backing field declared in A1
, since private members of a base type are not accessible through a derived type. (See also here: Are private members inherited in C#?)
Thus, when trying to compare two instances of type A2
- which itself does not declare any fields - using the Attribute.Equals implementation, the result will be true
(because the type of the two attribute instances is the same type A2
, and the instances do not feature any fields that would be accessible through the A2
type).
Possible solutions (depending on the actual application scenario at hand) could be (among other things) using public fields instead of public properties in attribute classes, or perhaps overriding the Equals()
method in your base attribute class (A1
) which reflects and compares the type, all public fields and additionally all public properties of two attribute instances.
推荐阅读
- javascript - discord.js 为用户获取每个列表以进行反应
- ios - 使用 MKMapKit 在 SwiftUI 中进行位置更新
- bash - 在 Bash 中向文件添加可变数量的行
- java - Cucumber和WebDriver,不需要的时候打开chrome
- python - PyQt5 中的无限循环
- c - 使用 SIGKILL 进行不间断系统调用期间的任务“死亡”状态
- r - R:我如何 c() 按另一列分组的嵌套字符向量?
- r - R - 无效的 'sep' 值:必须是一个字节
- javascript - 你能模拟活动开始前按住的 shift 键吗
- php - 如何自动获取 Google 驱动器刷新令牌