根据MSDN文档RandomNumberGenerator :
应用程序代码不直接使用这个类。 此抽象类是作为对所有加密随机数生成器的基类。
对于密码随机数生成器的实现,使用派生类RNGCryptoServiceProvider。
不过,我已经看到了在不同的代码库的几个occassions用下面的代码:
byte[] bytes = new byte[...];
RandomNumberGenerator rng = RandomNumberGenerator.Create();
rng.GetBytes(bytes);
最引人注目的是StackExchange (我假设包括SO),并与BCrypt.Net 。
因此,我有点困惑-是什么类型的RandomNumberGenerator
是上面的代码返回? 也就是这一点,一些代码库使用的缺陷RandomNumberGenerator
而非RNGCryptoServiceProvider
?
我认为RandomNumberGenerator.Create()
是我在这里完全缺失的引擎盖下做的,但在技术上(因为它是一个抽象类)不应该在上面的代码抛出一个错误?
该RandomNumberGenerator.Create()
方法调用RandomNumberGenerator.Create("System.Security.Cryptography.RandomNumberGenerator")
最终将创建一个实例RNGCryptoServiceProvider
。
(它确实有些查找一对字典的,所以很可能,你可以通过地方注册一个默认的随机数发生器改变调用的行为。)
对象的实际类型返回在编译的时候不知道,它只是知道它会继承RandomNumberGenerator
类,所以你可以使用一个RandomNumberGenerator
引用变量它。
创建不同类型取决于输入实例中的这种方式在几个框架中的位置由所使用的,例如WebRequest.Create
方法。
有人在项目建立在微软已“固定”为当前文档(框架4.5) Create()
方法。 现在说:
“当在派生类重写时,创建密码学随机数发生器,可以被用于产生随机数据的默认实现的一个实例。”
为框架4.0的文档说:
“创建密码学随机数发生器,可以被用于产生随机数据的默认实现的一个实例。”
这是该方法所做的正确描述。 我会提出一个要求把这样的描述后面的新文档。
对于文档RandomNumberGenerator
基本上是搞砸了。 再举一个例子,有这样的文件:
当在派生类重写时,创建指定实现密码学随机数发生器的一个实例。
......一个静态方法。 静态方法不能被重写。 谁写的文件显然不是直线思维。
我怀疑的初衷是这样的:
应用程序代码不直接实例化这个类。 此抽象类是作为对所有加密随机数生成器的基类。
我想你已经发布的代码(使用静态Create
方法)是完全合理的。 这是同一种模式作为用于XmlReader.Create
等-静态方法选择最合适的实现。
RandomNumberGenerator.Create
是一个静态的工厂方法。 当然,它会返回一个派生类的实例。 而那一个不是抽象的,因此所有的,这是合法的。
抽象类是用来被到处使用使用更具体的类来代替。 他们注定是一个版本,友好的界面。