8protons
8protons

Reputation: 3959

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. Below, we do just that for parent class Animal and child class 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:

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.

When comparing both these Hominoidea classes as Animals, how does the compiler invoke the correct virtual object.Equals() method inside the static operator method? I thought everything inside a static method had to also be static?

Upvotes: 2

Views: 405

Answers (2)

Racil Hilan
Racil Hilan

Reputation: 25351

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.

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. So you can write this code:

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

Upvotes: 4

John Wu
John Wu

Reputation: 52240

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

Upvotes: 4

Related Questions