在为自定义对象编写自己的相等逻辑时,可以做一些事情。其中两种做法包括重载==
运算符并覆盖obj.Equals()
方法。
下面,我们为父类Animal
和子类Hominoidea
执行此操作。
public class Animal
{
public static bool operator ==(Animal x, Animal y)
{
return object.Equals(x, y);
}
public override bool Equals(object obj)
{ ... }
...
}
public class Hominoidea : Animal
{
public static bool operator ==(Hominoidea x, Hominoidea y)
{
return object.Equals(x, y);
}
public override bool Equals(object obj)
{ ... }
...
}
如果我们能够轻松地比较一种动物的方式而不管它们的派生类(Hominoidea,Felidae等),我们可以利用基类的简单逻辑并且可能会写类似的东西:
static void DisplayWhetherEqual(Animal animal1, Animal animal2)
{
if (animal1 == animal2)
{
Console.WriteLine(string.Format("{0,12} == {1}", animal1, animal2));
}
else
Console.WriteLine(string.Format("{0,12} != {1}", animal1, animal2));
}
如果我们传入Hominoidea
个对象,代码将首先执行static
类的==
重载Animal
,然后执行虚拟object.Equals(x, y)
子类,Hominoidea
类。
将这两个Hominoidea
类比较为Animal
时,编译器如何在object.Equals()
运算符方法中调用正确的虚拟static
方法?我认为static
方法中的所有内容都必须是static
?
答案 0 :(得分:4)
静态方法当然可以访问实例方法;没有它们,你将无法做任何有趣的事情。静态类缺少的是它自己的实例(关键字this
在静态方法中是未定义的)。但是,您可以在传递给它的任何对象上调用实例方法,或以其他方式使其可用。
所以虽然你不能这样做
class MyClass
{
static void Print()
{
Console.WriteLine(this.ToString()); //Does not compile
}
}
你当然可以做到这一点
class MyClass
{
static void Print(MyClass instance)
{
Console.WriteLine(instance.ToString()); //Compiles, because it references an object that was passed in
}
}
这个
class MyClass
{
static private MyClass _anInstance = new MyClass();
static void Print()
{
Console.WriteLine(_anInstance.ToString()); //Compiles, because it references an object instance held in a static variable
}
}
答案 1 :(得分:4)
我认为静态方法中的所有内容都必须是静态的
是什么让你这么认为?没有这样的规则。静态方法没有附加到类的特定实例(这就是他们在VB中将它们称为Shared
的原因,这意味着它们在所有实例之间共享),但除此之外它们与实例方法没有区别。
考虑一下
public class Person {
public string FirstName { get; set; }
public string LastName { get; set; }
public static string GetInitials(Person person) {
return person.FirstName[0].ToString() + person.LastName[0].ToString();
}
}
static
方法GetInitials()
可以访问传递给它的实例的属性。所以你可以写这段代码:
var p = new Person();
p.FirstName = "Joe";
p.LastName = "Smith";
Console.WriteLine(Person.GetInitials(p));