简体   繁体   中英

How does a method in an abstract base class call the constructor from a derived class?

As an example, consider the .NET SHA256Managed class.

SHA256Managed inherits from the abstract class, SHA256 , which has a method named Create(). The documentation says Create() instantiates an instance of the default implementation of SHA256.

I would have been likely to write something like

using (SHA256Managed Sha256Managed = new SHA256Managed())
{
  // code
}

Whereas Microsoft's example opts to use:

SHA256 mySHA256 = SHA256Managed.Create();

How does the method like Create() (from a base class), instantiate an instance of a class that derives from it?

A function can return an instance of whatever you want it to ;)

In this case, an instance of 256Managed is still castable to SHA256

Something like this is entirely feasible:

public class SHA256Managed 
{
   public static SHA256 Create() 
   {
       return new SHA256Managed();
   }
}

Method or property of a class can use any derived classes (or even itself as fields) as much as it wants. There is no restrictions in language that a method can only use objects of its own and base class.

The only thing you can't do with abstract class is to new an instance of such class, calling static member of such class that returns whatever valid instance of any non-abstract class/struct is perfectly fine.

Following valid code shows that it is possible to return either your own or even derived class:

class Base 
{
  public Derived Property1 {get;set;}
  public Base Property2 {get;set;}      

  public static Base Create()
  {
    return new Derived();
  }

  public static Derived Create2()
  {
    return new Derived();
  }
}

class Derived : Base
{
}

Usually, base classes shouldn't have any knowledge its of derived classes - it can however instantiate whatever it wants.

In the case of SHA256 however, its Create() method "instantiates the default implementation", which is listed as SHA256Managed. Because SHA256Managed doesn't have a create method, it calls its base class' Create() and gets an instance of itself back. This can only happen if the base implementation explicitly instantiates SHA256Managed like Alexei + Tom have shown:

        public static SHA256 Create()
        {
            return new SHA256Managed();
        }

In the SHA256 class, the Create method is a static method that returns 'an instance of the default implementation of System.Security.Cryptography.SHA256' (according to the method documentation). This default implementation is SHA256Managed - a non-abstract child class of SHA256 .

The SHA256 and SHA256Managed classes are defined in the same assembly, so SHA256Managed is available to SHA256.Create as a valid class.

Here's an example of an abstract base class with a static Create method that creates an instance of a non-abstract derived class:

public abstract class A
{
    public static A Create()
    {
        return new B();
    }

    public abstract void DoSomething();
}

public class B : A
{
    public override void DoSomething()
    {
        // do nothing.
    }
}

Effectively what happens is the compiler builds a list of the classes and their members for your entire assembly before it compiles the code for those members. So by the time the A.Create method is being compiled the compiler already knows about the existence and structure of class B .

That's also why it is OK to put properties and methods in a class after the first point where you refer to them, like so:

class C
{
    void some_method()
    {
        ++counter;
    }

    int counter;
}

The compiler already knows the entire structure of class C before it compiles the code for some_method so it can compile the statement ++counter; without errors.

if i am not mistaken you are thinking of SHA256Managed.Create() is calling the Create() method of the SHA256 the base class.

Create() method is a static method which is not overrideable, it is implemented on SHA256Managed class with new keyword. se here for more info

EDIT

So, after digging deeper (using ILSPY) i found that Create() method of SHA256 isn't that simple, it is call another class CryptoConfig.CreateFromName . just a guess the information about SHA256Managed (derived class) is reside in some configuration mechanism.

@ 280Z28 : thak you for your correction

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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