当 class 从接口派生时,C# 重写运算符 ==。我可以在接口中使用 == 还是如何防止它
C# Overriding operator == when class derives from interface. Can I use == with interface or how to prevent it
我继承了一些代码,其中 Equals 被覆盖但没有 ==。我解决了这个问题,但我发现了更多问题。在调用代码中,对象是使用接口构造的,然后进行比较,结果不是人们所期望的。我在下面放了一个完整的最小示例。
简而言之,给定 ISilly i1 = new Silly() 和 ISilly i2 = new Silly,i1==i2 return 为假,不为真。有没有办法解决这个问题,我应该这样做吗?我看到了一些类似 "i1 and i2 are interaces. There could be many classes that derive from ISilly so asking if i1 and i2 doesn't make sense except in a reference equality sense" 的论点。如果这是答案,我的两个问题是:
- 为什么 Equals 工作得这么漂亮?
- 如何阻止应用程序程序员调用 "i1 == i2"? him/her 比 i1.Equals(i2).
更自然
我尝试输入 public static bool operator ==(ISilly s1, ISilly s2)- 注意接口而不是 class 名称。我收到编译器错误。
我在这里错过了什么?我曾尝试搜索一篇没有运气的文章来解决这个问题。我还以为这是一个普遍的问题。
如果有任何不清楚的地方请告诉我,或者我可以提供更多信息。
谢谢,
戴夫
更新!!!
我刚刚发现了这个相关问题:
Operator Overloading with Interface-Based Programming in C#
在我阅读它时,答案似乎表明您不能将 == 与接口一起使用,其中一个答案建议使用第三方工具(例如 Resharper)来禁止它。考虑到它可能产生的严重错误,我完全怀疑 == 的用处。为什么还要允许呢?
namespace EqualityProblems
{
class Program
{
static void Main(string[] args)
{
// just use class, not interface!
Silly s1 = new Silly();
Silly s2 = new Silly();
Silly s3 = new Silly(42);
Silly s4 = null;
Silly s5 = null;
Console.WriteLine("s1.Equals(s2) should be true " + s1.Equals(s2)); // should be true
Console.WriteLine("s1.Equals(s3) should be false " + s1.Equals(s3)); // should be false
Console.WriteLine("s1.Equals(s4) should be false " + s1.Equals(s4)); // should be false
Console.WriteLine("s1 == s2 should be true " + (s1 == s2)); // should be true
Console.WriteLine("s1 != s2 should be false " + (s1 != s2)); // should be false
Console.WriteLine("s1 == s3 should be false " + (s1 == s3)); // should be false
Console.WriteLine("s4 == s1 should be false " + (s4 == s1)); // should be false
Console.WriteLine("s1 == s4 should be false " + (s1 == s4)); // should be false
Console.WriteLine("s4 == s5 should be true " + (s4 == s5)); // should be true;both are null
//Console.WriteLine("s4.Equals(s1) should crash " + s4.Equals(s1)); // should crash. s4 is null
ISilly i1 = new Silly();
ISilly i2 = new Silly();
ISilly i3 = new Silly(42);
ISilly i4 = null;
ISilly i5 = null;
Console.WriteLine("i1.Equals(i2) should be true " + i1.Equals(i2)); // should be true
Console.WriteLine("i1.Equals(i3) should be false " + i1.Equals(i3)); // should be false
Console.WriteLine("i1.Equals(i4) should be false " + i1.Equals(i4)); // should be false
Console.WriteLine("i1 == i2 should be true " + (i1 == i2)); // should be true BUT IS FALSE
Console.WriteLine("i1 != i2 should be false " + (i1 != i2)); // should be false BUT IS TRUE
Console.WriteLine("i1 == i3 should be false " + (i1 == i3)); // should be false
Console.WriteLine("i4 == i1 should be false " + (i4 == i1)); // should be false
Console.WriteLine("i1 == i4 should be false " + (i1 == i4)); // should be false
Console.WriteLine("i4 == i5 should be true " + (i4 == i5)); // should be true;both are null
//Console.WriteLine("i4.Equals(i1) should crash " + i4.Equals(i1)); // should crash. i4 is null
}
}
public interface ISilly
{
int Length { get; set; }
}
public class Silly : ISilly
{
public Silly(int n) { Length = n; }
public Silly() { Length = 7; }
public int Length { get; set; }
public override bool Equals(object obj)
{
return obj is ISilly sl && (sl.Length == Length);
}
public bool Equals(Silly other)
{
if (other == null) return false;
return Length == other.Length;
}
public override int GetHashCode()
{
return Length;
}
public static bool operator ==(Silly s1, Silly s2)
{
if (ReferenceEquals(s1, null))
{
return ReferenceEquals(s2, null) ? true : false;
}
return s1.Equals(s2);
}
public static bool operator !=(Silly fs1, Silly fs2)
{
return !fs1.Equals(fs2);
}
}
}
不知道这对你是否可行,但如果你可以使用抽象 class 而不是接口,你可以做的是将 == 运算符实现为对抽象 Equals( ).
这样任何人在派生的 class 上使用 == 都会得到与调用 Equals 相同的结果。
应用于两个接口引用的 operator ==
和 operator !=
比较引用,因为这些接口没有运算符重载的可能性,因为它们是静态方法。
CLR 无法调用它们。
How do I override the equals operator == for an Interface in C#?
的副本
我继承了一些代码,其中 Equals 被覆盖但没有 ==。我解决了这个问题,但我发现了更多问题。在调用代码中,对象是使用接口构造的,然后进行比较,结果不是人们所期望的。我在下面放了一个完整的最小示例。 简而言之,给定 ISilly i1 = new Silly() 和 ISilly i2 = new Silly,i1==i2 return 为假,不为真。有没有办法解决这个问题,我应该这样做吗?我看到了一些类似 "i1 and i2 are interaces. There could be many classes that derive from ISilly so asking if i1 and i2 doesn't make sense except in a reference equality sense" 的论点。如果这是答案,我的两个问题是:
- 为什么 Equals 工作得这么漂亮?
- 如何阻止应用程序程序员调用 "i1 == i2"? him/her 比 i1.Equals(i2). 更自然
我尝试输入 public static bool operator ==(ISilly s1, ISilly s2)- 注意接口而不是 class 名称。我收到编译器错误。
我在这里错过了什么?我曾尝试搜索一篇没有运气的文章来解决这个问题。我还以为这是一个普遍的问题。
如果有任何不清楚的地方请告诉我,或者我可以提供更多信息。 谢谢, 戴夫
更新!!! 我刚刚发现了这个相关问题: Operator Overloading with Interface-Based Programming in C# 在我阅读它时,答案似乎表明您不能将 == 与接口一起使用,其中一个答案建议使用第三方工具(例如 Resharper)来禁止它。考虑到它可能产生的严重错误,我完全怀疑 == 的用处。为什么还要允许呢?
namespace EqualityProblems
{
class Program
{
static void Main(string[] args)
{
// just use class, not interface!
Silly s1 = new Silly();
Silly s2 = new Silly();
Silly s3 = new Silly(42);
Silly s4 = null;
Silly s5 = null;
Console.WriteLine("s1.Equals(s2) should be true " + s1.Equals(s2)); // should be true
Console.WriteLine("s1.Equals(s3) should be false " + s1.Equals(s3)); // should be false
Console.WriteLine("s1.Equals(s4) should be false " + s1.Equals(s4)); // should be false
Console.WriteLine("s1 == s2 should be true " + (s1 == s2)); // should be true
Console.WriteLine("s1 != s2 should be false " + (s1 != s2)); // should be false
Console.WriteLine("s1 == s3 should be false " + (s1 == s3)); // should be false
Console.WriteLine("s4 == s1 should be false " + (s4 == s1)); // should be false
Console.WriteLine("s1 == s4 should be false " + (s1 == s4)); // should be false
Console.WriteLine("s4 == s5 should be true " + (s4 == s5)); // should be true;both are null
//Console.WriteLine("s4.Equals(s1) should crash " + s4.Equals(s1)); // should crash. s4 is null
ISilly i1 = new Silly();
ISilly i2 = new Silly();
ISilly i3 = new Silly(42);
ISilly i4 = null;
ISilly i5 = null;
Console.WriteLine("i1.Equals(i2) should be true " + i1.Equals(i2)); // should be true
Console.WriteLine("i1.Equals(i3) should be false " + i1.Equals(i3)); // should be false
Console.WriteLine("i1.Equals(i4) should be false " + i1.Equals(i4)); // should be false
Console.WriteLine("i1 == i2 should be true " + (i1 == i2)); // should be true BUT IS FALSE
Console.WriteLine("i1 != i2 should be false " + (i1 != i2)); // should be false BUT IS TRUE
Console.WriteLine("i1 == i3 should be false " + (i1 == i3)); // should be false
Console.WriteLine("i4 == i1 should be false " + (i4 == i1)); // should be false
Console.WriteLine("i1 == i4 should be false " + (i1 == i4)); // should be false
Console.WriteLine("i4 == i5 should be true " + (i4 == i5)); // should be true;both are null
//Console.WriteLine("i4.Equals(i1) should crash " + i4.Equals(i1)); // should crash. i4 is null
}
}
public interface ISilly
{
int Length { get; set; }
}
public class Silly : ISilly
{
public Silly(int n) { Length = n; }
public Silly() { Length = 7; }
public int Length { get; set; }
public override bool Equals(object obj)
{
return obj is ISilly sl && (sl.Length == Length);
}
public bool Equals(Silly other)
{
if (other == null) return false;
return Length == other.Length;
}
public override int GetHashCode()
{
return Length;
}
public static bool operator ==(Silly s1, Silly s2)
{
if (ReferenceEquals(s1, null))
{
return ReferenceEquals(s2, null) ? true : false;
}
return s1.Equals(s2);
}
public static bool operator !=(Silly fs1, Silly fs2)
{
return !fs1.Equals(fs2);
}
}
}
不知道这对你是否可行,但如果你可以使用抽象 class 而不是接口,你可以做的是将 == 运算符实现为对抽象 Equals( ).
这样任何人在派生的 class 上使用 == 都会得到与调用 Equals 相同的结果。
operator ==
和 operator !=
比较引用,因为这些接口没有运算符重载的可能性,因为它们是静态方法。
CLR 无法调用它们。
How do I override the equals operator == for an Interface in C#?
的副本