简体   繁体   English

静态方法如何调用虚方法?

[英]How can a static method invoke a virtual method?

There are a few things one can do when writing one's own equality logic for custom objects. 在为自定义对象编写自己的相等逻辑时,可以做一些事情。 Two of those practices include overloading the == operator and overriding the obj.Equals() method. 其中两个实践包括重载==运算符并覆盖obj.Equals()方法。 Below, we do just that for parent class Animal and child class Hominoidea . 下面,我们为父类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)
   { ... }

   ...
}

In the case that we went to be able to easily compare a manner of animals regardless of their derived classes (Hominoidea, Felidae, etc), we'd take advantage of the simple logic of the base class and maybe write something like: 在我们能够轻松比较动物的方式而不管它们的派生类(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));
}

If we pass in Hominoidea objects, the code will first execute the static overload == for the Animal class but then execute the virtual object.Equals(x, y) for the child class, Hominoidea class. 如果我们传入Hominoidea对象,代码将首先为Animal类执行static重载== ,然后为子类Hominoidea类执行虚拟object.Equals(x, y) Hominoidea object.Equals(x, y)

When comparing both these Hominoidea classes as Animal s, how does the compiler invoke the correct virtual object.Equals() method inside the static operator method? 将这些HominoideaAnimal编译器如何在static运算符方法中调用正确的虚拟object.Equals()方法? I thought everything inside a static method had to also be static ? 我认为static方法中的所有内容都必须是static

Static methods can certainly access instance methods; 静态方法当然可以访问实例方法; you wouldn't be able to do anything very interesting without them. 没有它们,你将无法做任何有趣的事情。 The thing a static class lacks is its own instance (the keyword this is undefined from inside a static method). 静态类缺少的东西是它自己的实例(关键字this是从一个静态方法中未定义)。 But you can call instance methods on any object that is passed to it or otherwise made available. 但是您可以在传递给它或以其他方式可用的任何对象上调用实例方法。

So while you cannot do this 所以,虽然你不能这样做

class MyClass
{
    static void Print()
    {
        Console.WriteLine(this.ToString());  //Does not compile
    }
}

you most certainly can do this 你当然可以做到这一点

class MyClass
{
    static void Print(MyClass instance)
    {
        Console.WriteLine(instance.ToString());  //Compiles, because it references an object that was passed in
    }
}

And this 和这个

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
    }
}

I thought everything inside a static method had to also be static 我认为静态方法中的所有内容都必须是静态的

What made you think so? 是什么让你这么想的? There is no such a rule. 没有这样的规则。 Static methods are not attached to a specific instance of the class (that's why they call them Shared in VB, meaning they're shared between all instances), but otherwise they are no different from instance methods. 静态方法没有附加到类的特定实例(这就是为什么他们称之为在VB中Shared ,这意味着它们在所有实例之间共享),但是否则它们与实例方法没有区别。

Consider this 考虑一下

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();
    }
}

The static method GetInitials() can access the properties of the instance that is passed to it. static方法GetInitials()可以访问传递给它的实例的属性。 So you can write this code: 所以你可以写这段代码:

var p = new Person();
p.FirstName = "Joe";
p.LastName = "Smith";
Console.WriteLine(Person.GetInitials(p));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM