1

例如,考虑.NET SHA256Managed类。

SHA256Managed 继承自抽象类SHA256,它有一个名为 Create() 的方法。文档说 Create() 实例化了 SHA256 的默认实现的一个实例。

我可能会写类似的东西

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

而微软的例子选择使用:

SHA256 mySHA256 = SHA256Managed.Create();

Create() 之类的方法(来自基类)如何实例化派生自它的类的实例?

4

5 回答 5

2

一个函数可以返回一个你想要它的实例;)

在这种情况下, 的实例256Managed仍然可以转换为SHA256

这样的事情是完全可行的:

public class SHA256Managed 
{
   public static SHA256 Create() 
   {
       return new SHA256Managed();
   }
}
于 2013-06-07T00:22:58.570 回答
0

通常,基类不应该对派生类有任何了解——但是它可以实例化它想要的任何东西。

然而,在 SHA256 的情况下,它的 Create() 方法“实例化了默认实现”,它被列为 SHA256Managed。因为 SHA256Managed 没有 create 方法,所以它调用它的基类 Create() 并取回它自己的一个实例。这只有在基本实现明确实例化 SHA256Managed 时才会发生,就像 Alexei + Tom 所示:

        public static SHA256 Create()
        {
            return new SHA256Managed();
        }
于 2013-06-07T02:08:41.330 回答
0

类的方法或属性可以根据需要使用任何派生类(甚至其本身作为字段)。语言没有限制方法只能使用它自己的对象和基类。

对抽象类唯一不能做的就是对new此类的一个实例,调用此类返回任何非抽象类/结构的任何有效实例的静态成员非常好。

以下有效代码表明可以返回您自己的甚至派生类:

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
{
}
于 2013-06-07T00:40:27.670 回答
0

SHA256该类中,该Create方法是一个静态方法,它返回“System.Security.Cryptography.SHA256 的默认实现的实例”(根据方法文档)。此默认实现是SHA256Managed- 的非抽象子类SHA256

和类在同一个程序集中定义,因此SHA256可用作有效类。SHA256ManagedSHA256ManagedSHA256.Create

下面是一个抽象基类的示例,它具有一个Create创建非抽象派生类的实例的静态方法:

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

实际上,编译器会在为这些成员编译代码之前为整个程序集构建类及其成员的列表。因此,在A.Create编译方法时,编译器已经知道 class 的存在和结构B

这也是为什么可以在引用它们的第一个点之后将属性和方法放在类中的原因,如下所示:

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

    int counter;
}

C编译器在编译代码之前已经知道类的整个结构,some_method因此它可以编译语句++counter;而不会出错。

于 2013-06-07T02:24:39.363 回答
-1

如果我没记错的话,您正在考虑SHA256Managed.Create()调用基类的Create()方法。SHA256

Create()方法是一个不可覆盖的静态方法,它是在SHA256Managed带有new关键字的类上实现的。在这里查看更多信息

编辑

因此,在深入挖掘(使用 ILSPY)之后,我发现Create()方法SHA256并不是那么简单,它是调用另一个类CryptoConfig.CreateFromName。只是猜测有关SHA256Managed(派生类)的信息存在于某些配置机制中。

@ 280Z28 : 谢谢你的指正

于 2013-06-07T00:59:51.410 回答