RandomNumberGenerator vs RNGCryptoServiceProvider

The RandomNumberGenerator.Create() method calls RandomNumberGenerator.Create("System.Security.Cryptography.RandomNumberGenerator"), which will eventually create an instance of RNGCryptoServiceProvider.

(It does some lookups in a pair of dictionaries, so it's likely that you can change the behaviour of that call by registering a default random generator somewhere.)

The actual type of the object returned is not known at compile time, it's only known that it will inherit the RandomNumberGenerator class, so you can use a RandomNumberGenerator reference variable for it.

This way of creating different types of instances depending on the input is used in a couple of places in the framework, for example by the WebRequest.Create method.


Someone at Micrsoft has "fixed" the current documentation (framework 4.5) for the Create() method. It now says:

"When overridden in a derived class, creates an instance of the default implementation of a cryptographic random number generator that can be used to generate random data."

The documentation for framework 4.0 says:

"Creates an instance of the default implementation of a cryptographic random number generator that can be used to generate random data."

This is the correct description of what the method does. I will put in a request to put that description back in the newer documentation.


The documentation for RandomNumberGenerator is basically messed up. As another example, there's documentation like this:

When overridden in a derived class, creates an instance of the specified implementation of a cryptographic random number generator.

... for a static method. Static methods can't be overridden. Whoever wrote the documentation clearly wasn't thinking straight.

I suspect the original intention was something like:

Application code does not directly instantiate this class. This abstract class is provided as the base class for all cryptographic random number generators.

I think the code you've posted (using the static Create method) is entirely reasonable. It's the same sort of pattern as is used for XmlReader.Create etc - the static method chooses the most appropriate implementation.