对象创建中var和Class类之间的区别

时间:2013-11-10 15:48:21

标签: c# .net visual-studio-2010 c#-4.0

这是一个愚蠢的问题,但看到不同的行为却感到震惊。学到很多东西。

假设我有以下两个课程

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的对象。我们在哪里使用这种风格?只有在使用运行时多态时? (重写方法)?

3 个答案:

答案 0 :(得分:3)

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

因此,您的声明

var c = new C();

,变量c将声明为C类型。

如果您希望c包含任何其他类型,则基本上有两种选择:

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

至于你更详细的问题:

  • B c = new C()创建类型为C的实例。这就是new C()的作用。变量c被键入B这一事实仅意味着编译器将假定c具有B类型的任何属性和方法,但不一定是C类型1}}。同样,您不仅可以在以后将[{1}}类型的实例以及C类型的实例分配给B
  • 实际上,如果您不确定c是否会在某个时间引用类型为c的实例,而不是仅为B类型的实例,则可以使用此样式。

答案 1 :(得分:3)

B c = new C();相当于B c = (B)(new C());编译器将new C()隐式转换为B,这是合法的,因为C派生自Bvar 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

答案 2 :(得分:2)

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

C c = new C();

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