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.