2

这是一个愚蠢的问题,但看到不同的行为感到震惊。学习了不少。

假设我在下面有两个课程

Class A
{
 public void Display()
 {
 }
}

Class B : A
{
 public void Display()
 {
 }
}

Class C : B
{
 public void Display()
 {
 }
}

Class Final
{
 static void Main()
 {
  var c = new C();
//  B c = new C();  

 }
}

我的疑问是,以上两种方法都给出了不同的结果。我可以知道B c = new C()创建 B 或 C 的对象吗?我的理解是,它创建了 B 的对象。那我们为什么说new C()?我同意C c = new C();但我想,B b = new C();创建 B 的对象。我们在哪里使用这种风格?仅在使用运行时多态性时?(覆盖方法)?

4

3 回答 3

3

使用var关键字声明变量时,编译器会从赋值的右侧推断变量的类型。特别是,它使用赋值运算符 ( ) 右侧的表达式=求值的类型。

因此,对于您的声明

var c = new C();

,变量c将被声明为 type C

如果你想c拥有任何其他类型,基本上有两种选择:

  • 要么c明确指明类型:B c = new C();
  • 或者,您可以更改右侧表达式以被识别为选择类型:var c = (B)(new C());

至于你更详细的问题:

  • B c = new C()创建一个类型的实例C。就是new C()这样。变量c的类型B仅意味着编译器将假定它c具有任何类型的属性和方法B,但不一定是类型C。同样,您不仅可以分配 type 的实例C,还可以B稍后c分配 type 的实例。
  • 实际上,当您不确定是否c会在某个时候引用 type 的实例B,而不是仅引用type 的实例时,您可以使用这种样式C
于 2013-11-10T15:52:45.873 回答
3

B c = new C();相当于B c = (B)(new C());编译器隐式转换new C()B合法的,因为C派生自B. var c = new C();简单地编译为C c = new C();从值推断类型。

看看这个:

class B : A
{
    public virtual void Display()
    {
        Console.WriteLine("B");
    }
}

class C : B
{
    public override void Display()
    {
        Console.WriteLine("C");
    }
}

B c = new C();

c.Display(); // write C not B
于 2013-11-10T15:57:37.483 回答
2

var使用类型推断从您初始化它的表达式的编译时类型推断变量的类型。
由于new C()is 的类型C,您var的等价于:

C c = new C();

由于您的Display()方法不是虚拟的,因此调用哪个方法取决于您调用它的表达式的编译时类型。

于 2013-11-10T15:52:04.580 回答