这是一个愚蠢的问题,但看到不同的行为却感到震惊。学到很多东西。
假设我有以下两个课程
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的对象。我们在哪里使用这种风格?只有在使用运行时多态时? (重写方法)?
答案 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
派生自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
答案 2 :(得分:2)
var
使用类型推断从您初始化它的表达式的编译时类型推断变量的类型。
由于new C()
的类型为C
,因此您的var
是等效的:
C c = new C();
由于您的Display()
方法不是虚拟的,因此调用哪个方法取决于您调用它的表达式的编译时类型。