c# - 如何选择运算符 ==?
问题描述
internal static class ChoosingEqOperTest
{
class A
{
public static bool operator ==(A a, A a2) => false;
}
class B:A
{
public static bool operator ==(B a, B a2) => true;
}
static void CheckChosenOper<T>(T x, T x2) where T : A
{
Console.WriteLine(x==x2);
}
internal static void Do()
{
var a = new A();
var a2 = new A();
var b = new B();
var b2 = new B();
CheckChosenOper(a,a2); // 1. "False"
CheckChosenOper(b,b2); // 2. "False" !?
CheckChosenOper<A>(a,a2); // 3. "False"
CheckChosenOper<A>(b, b2); // 4. "False"
//CheckChosenOper<B>(a, a2); //Complie Error
CheckChosenOper<B>(b, b2); // 5. "False" !?
Console.WriteLine(a == a2); // 6. "False"
Console.WriteLine(b == b2); // 7. "True"
Console.WriteLine(a == b2); // 8. "False"
Console.WriteLine(b == a2); // 9. "False"
}
}
一些问题:
A) 为什么#2 & #5 打印“False”?B
- 我希望在这些情况下应该从类中获取运算符实现。
B) 我是对的:由于 #8 和 #9 都打印“False” - Cosen 运算符实现是第一个发现的,两种事实参数类型都可以转换为它的参数类型?
c) 选择运算符 == 实现的常见规则是什么?
解决方案
A)好吧,您的方法是一个通用方法,即使您有意指定类型CheckChosenOper
,它仍然“使用”类 A 作为基类并且它是自己的运算符。似乎运算符在派生类中没有被覆盖,并且方法只能使用它已知的东西:A类。它不能自行运行并使用反射来搜索其他有效的相等运算符。==
<B>
CheckChosenOper
B) 不,你错了。在 #8 和 #9 的情况下,编译器有两个选择 - 将 A 向上转换为 B 并将 B1 与 B2 进行比较,将 B 向下转换为 A 并将 A1 与 A2 进行比较。由于向上转换是一个禁忌并且必须通过转换运算符专门完成,因此编译器采用简单的 A1==A2 选择。
C) 好吧,如果我在写一个struct
,我肯定会去写一个。以及!=
, GetHashCode
,IEquatable<>
和其他一些东西。但是必须有充分的理由来创建自己的结构,因为它们的行为不同。
推荐阅读
- java - 为什么活动没有开始?
- haskell - Haskell:可能的原因:'(:)' 应用于太多参数
- python - 如何在 on_ready 事件 discord.py 中向所有成员发送消息
- django - Docker Compose Django + PostgreSQL 访问 postgres 主机而不使用服务名
- react-native - 如何为 React Animation 重复最后几帧动画
- database - 数据库模式设计
- python - 使用 __init__.py 导入导致 NameError: name '...' is not defined
- python - Pytorch RuntimeError:预期的标量类型 Long 但发现 Int
- android - 如何在本地从 firebase 中删除查询的数据?
- javascript - 将 TradingView 小部件嵌入到角度组件中