问题描述
据我了解,记录实际上是类,它们以对象为值驱动而不是引用为驱动的方式实现自己的相等性检查。
简而言之,对于@bot.command()
async def foo(ctx,user: discord.User):
print(user.id)
和record Foo
这样实现的var foo = new Foo { Value = "foo" }
,var bar = new Foo { Value = "foo" }
表达式将得出foo == bar
,即使它们有不同的引用(True
)。
现在有了记录,即使.Net Blog中发布的the article中的记录显示为:
如果您不喜欢默认的逐域比较行为 生成的Equals替代,您可以编写自己的替代。
当我尝试放置ReferenceEquals(foo,bar) // False
或public override bool Equals
或public override int GetHashCode
等时,我遇到了public static bool operator ==
错误,因此我认为这是受限制的行为,Member with the same signature is already declared
对象则不是这种情况。
struct
编译器结果:
public sealed record SimpleVo
: IEquatable<SimpleVo>
{
public bool Equals(SimpleVo other) =>
throw new System.NotImplementedException();
public override bool Equals(object obj) =>
obj is SimpleVo other && Equals(other);
public override int GetHashCode() =>
throw new System.NotImplementedException();
public static bool operator ==(SimpleVo left,SimpleVo right) =>
left.Equals(right);
public static bool operator !=(SimpleVo left,SimpleVo right) =>
!left.Equals(right);
}
我的主要问题是,如果我们要自定义平等检查器的工作方式,该怎么办?我的意思是,我的确知道这超出了记录的全部目的,但另一方面,平等检查器并不是使记录使用起来很酷的唯一功能。
一个人想要覆盖记录相等性的用例是,因为您可能有一个attribute,该属性将从相等性检查中排除某个属性。以this SimpleVo.cs(11,30): error CS0111: Type 'SimpleVo' already defines a member called 'Equals' with the same parameter types
SimpleVo.cs(17,37): error CS0111: Type 'SimpleVo' already defines a member called 'op_Equality' with the same parameter types
SimpleVo.cs(20,37): error CS0111: Type 'SimpleVo' already defines a member called 'op_Inequality' with the same parameter types
实现为例。
然后,如果您像这样扩展这个ValueObject
抽象类:
ValueObject
然后您将获得以下results:
public sealed class FullNameVo : ValueObject
{
public FullNameVo(string name,string surname)
{
Name = name;
Surname = surname;
}
[IgnoreMember]
public string Name { get; }
public string Surname { get; }
[IgnoreMember]
public string FullName => $"{Name} {Surname}";
}
到目前为止,为了实现上述用例,我已经实现了an abstract record object并像这样利用它:
var user1 = new FullNameVo("John","Doe");
var user2 = new FullNameVo("John","Doe");
var user3 = new FullNameVo("Jane","Doe");
Console.WriteLine(user1 == user2); // True
Console.WriteLine(ReferenceEquals(user1,user2)); // False
Console.WriteLine(user1 == user3); // True
Console.WriteLine(user1.Equals(user3)); // True
结果如下:
public sealed record FullNameVo : ValueObject
{
[IgnoreMember]
public string Name;
public string Surname;
[IgnoreMember]
public string FullName => $"{Name} {Surname}";
}
总而言之,我有点困惑,是限制记录对象的相等方法的覆盖是一种预期的行为,还是因为它仍处于预览阶段?如果是设计使然,您会以不同的(更好)方式实现上述行为,还是继续使用类?
var user1 = new FullNameVo
{
Name = "John",Surname = "Doe"
};
var user2 = new FullNameVo
{
Name = "John",Surname = "Doe"
};
var user3 = user1 with { Name = "Jane" };
Console.WriteLine(user1 == user2); // True
Console.WriteLine(ReferenceEquals(user1,user2)); // False
Console.WriteLine(user1 == user3); // False
Console.WriteLine(user1.Equals(user3)); // False
Console.WriteLine(ValueObject.EqualityComparer.Equals(user1,user3)); // True
输出:dotnet --version
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)