关于C#:将派生类强制转换为基类

Casting Deriving Class as Base Class

假设我有这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;

public class Program
{
    public static void Main()
    {
        BaseClass bc = new DerivedClass();
        bc.Method1();
        bc.Method2();
        Console.WriteLine(bc.GetType().FullName);

        // Output
        // Derived - Method1 (override)
       // Base - Method2
       // DerivedClass
    }
}

public class BaseClass
{
    public virtual void Method1()
    {
        Console.WriteLine("Base - Method1");
    }

    public virtual void Method2()
    {
        Console.WriteLine("Base - Method2");
    }
}

public class DerivedClass : BaseClass
{
    public override void Method1()
    {
        Console.WriteLine("Derived - Method1 (override)");
    }

    public new void Method2()
    {
        Console.WriteLine("Derived - Method2 (new)");
    }
}

如果派生类的实例变量被强制转换为基类,并且该实例变量用于调用重写的方法,则用override关键字重写的方法将在派生类中执行该实现,而用new关键字重写的方法将在基类中执行该实现。

上面例子中的变量bc如何转换为基类?

我知道new关键字将重写派生类中的方法实现,当使用派生类的实例变量调用重写的方法时,它将被执行,但我不知道它是什么类型的转换。似乎既不是隐式的也不是显式的,可能是类型转换,但我被语法搞糊涂了。

感谢您的解释。


I know that the new keyword will override the method implementation in the deriving class

不,它不会重写基类的方法。它声明了一个新的、独立的方法,该方法的名称相同,具有相同的签名。其效果是隐藏在基类中声明的相同签名方法,有效地使基类中声明的相同签名方法的调用复杂化。

在您的示例中,没有任何"类型转换"。将类型转换想象为提供实例的特定视图,向用户公开类契约的特定部分。没什么,没什么。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
// instance of DerivedClass exposing its full contract via the 'dc' variable
DerivedClass dc = new DerivedClass();

// the same instance of DerivedClass exposing its contract limited to what's declared in BaseClass
BaseClass bc = dc;

// calling Method2 as newly declared in DerivedClass
dc.Method2();

// calling Method2 as declared in BaseClass—the following two lines are equivalent
bc.Method2();
((BaseClass)dc).Method2();


实际上,没有转化。只有你观察物体的方式。

  • 如果用基类眼镜查看它,您将看到所有的基类方法,其中包括派生类中重写的method1,但它不包括派生类中的新method2,因此您将只看到基类中的method2。
  • 如果用派生类眼镜查看它,您将看到所有的基类方法,其中包括派生类中的重写方法1,但现在它还将包括派生类中的新方法2。基类中的原始虚拟方法1将不可见。


啊,我刚刚发现了这个,我错了,我说这似乎不是一个隐含的转变…我一定是读过头了。

For reference types, an implicit conversion always exists from a class to any one of its direct or indirect base classes or interfaces. No special syntax is necessary because a derived class always contains all the members of a base class.

1
2
Derived d = new Derived();
Base b = d; // Always OK.

How is the variable bc in the above example cast to the Base Class?

它是一个隐式强制转换,当您将新的DerivedClass实例分配给BaseClass类型的变量时执行:

1
BaseClass bc = new DerivedClass();