C# - 在指向同一内存位置的子项和父项 类 之间使用等于运算符和方法
C# - Using equals operators and methods between child and parent classes pointing to the same memory location
所以,我搜索了整个 Whosebug,但似乎找不到我的问题的正确答案。
我的问题是,当子对象和父对象指向相同的内存位置时,它们之间的相等性比较是否 return 错误,如果是,为什么?意思是,我是否只比较单个指针?还是在后台发生了更多事情?这与问题有关 "How does the compiler "请参阅“对象的类型,并区分父项和子项(同时仍等同于它们的指针)?”
我试图通过查看参考资料来理解这一点 here and here。
代码示例,
ChildType childTypeObject = new ChildType();
ParentType parentTypeObject = childTypeObject as ParentType;
if (parentTypeObject == childTypeObject)
{
// Will this always get executed?
}
编辑:
(假设子 class 没有重载 == 运算符。因此,如果您愿意,可以改用 ReferenceEquals() 比较。)
Will equality comparison between a child object and a parent object ever return false when they point to the same memory location, and if so why?
好的,请看下面。
==
运算符可以重载,但编译器只能调用它知道的实现。如果只能应用基类型重载(即至少一个操作数只是基类型),则调用基类型实现,并且该实现很容易与派生类型实现不同。
这就是为什么重载 ==
操作符(和相关操作符)应该很少而且要小心。确保运算符的语义是一致的、可预测的,并符合人们对对象之间关系的直觉理解需要付出一些努力。
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
Base b = d;
Console.WriteLine($"b == d: {b == d}");
}
}
class Base
{
public static bool operator ==(Base b1, Base b2)
{
return false;
}
public static bool operator !=(Base b1, Base b2)
{
return true;
}
}
class Derived : Base
{
public static bool operator ==(Derived b1, Derived b2)
{
return true;
}
public static bool operator !=(Derived b1, Derived b2)
{
return false;
}
}
如果转换成功,第二个变量仍然是与第一个变量相同的引用,并且它们共享引用相等性。就运行时而言,它甚至是转换前的原始类型。
void Main()
{
B b = new B();
A a = b as A;
Console.WriteLine(a.GetType().Name); // Output B
}
public class A {}
public class B : A {}
除非您像 Peter 在他的回答中所做的那样更改运算符的实现(或者可能通过某种其他形式的 hackery),否则引用相等性应该成立。
所以,我搜索了整个 Whosebug,但似乎找不到我的问题的正确答案。
我的问题是,当子对象和父对象指向相同的内存位置时,它们之间的相等性比较是否 return 错误,如果是,为什么?意思是,我是否只比较单个指针?还是在后台发生了更多事情?这与问题有关 "How does the compiler "请参阅“对象的类型,并区分父项和子项(同时仍等同于它们的指针)?”
我试图通过查看参考资料来理解这一点 here and here。
代码示例,
ChildType childTypeObject = new ChildType();
ParentType parentTypeObject = childTypeObject as ParentType;
if (parentTypeObject == childTypeObject)
{
// Will this always get executed?
}
编辑:
(假设子 class 没有重载 == 运算符。因此,如果您愿意,可以改用 ReferenceEquals() 比较。)
Will equality comparison between a child object and a parent object ever return false when they point to the same memory location, and if so why?
好的,请看下面。
==
运算符可以重载,但编译器只能调用它知道的实现。如果只能应用基类型重载(即至少一个操作数只是基类型),则调用基类型实现,并且该实现很容易与派生类型实现不同。
这就是为什么重载 ==
操作符(和相关操作符)应该很少而且要小心。确保运算符的语义是一致的、可预测的,并符合人们对对象之间关系的直觉理解需要付出一些努力。
class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
Base b = d;
Console.WriteLine($"b == d: {b == d}");
}
}
class Base
{
public static bool operator ==(Base b1, Base b2)
{
return false;
}
public static bool operator !=(Base b1, Base b2)
{
return true;
}
}
class Derived : Base
{
public static bool operator ==(Derived b1, Derived b2)
{
return true;
}
public static bool operator !=(Derived b1, Derived b2)
{
return false;
}
}
如果转换成功,第二个变量仍然是与第一个变量相同的引用,并且它们共享引用相等性。就运行时而言,它甚至是转换前的原始类型。
void Main()
{
B b = new B();
A a = b as A;
Console.WriteLine(a.GetType().Name); // Output B
}
public class A {}
public class B : A {}
除非您像 Peter 在他的回答中所做的那样更改运算符的实现(或者可能通过某种其他形式的 hackery),否则引用相等性应该成立。