【问题标题】:Difference between var and Class class in object creationvar和Class类在对象创建中的区别
【发布时间】:2013-11-10 15:48:20
【问题描述】:

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

假设我在下面有两个类

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

【问题讨论】:

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


    【解决方案1】:

    使用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 类型。同样,您不仅可以将C 类型的实例分配给c,还可以在以后将B 类型的实例分配给c
    • 确实,当您不确定c 是否会在某些时候引用B 类型的实例,而不是专门C 类型的实例时,您可以使用此样式。

    【讨论】:

    • 谢谢映射器。但我不明白 B c = new C();它创建 C 类型但 B 类型的对象?在我上面的例子中,我真的不明白它的意义。我只是在学习并试图理解为什么我们这样使用。实时场景。
    • @Divine:变量包含对对象引用。变量的类型是对变量可以引用的对象类型的限制。当您说B c 时,这意味着c 是一个只能引用 类型B 兼容的对象的变量。由于C 是从B 派生的类,它与B 类型兼容,因此您可以将C 的引用存储在B 类型的变量中。
    • @EricLippert:非常感谢您帮助我理解,这是一个简明易懂的解释 :)。我现在明白了 :) :) 再次感谢您。 :)
    【解决方案2】:

    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
    

    【讨论】:

    • Alessandro,谢谢你让我明白了。所以“B c = new C();”意味着我们只能访问 B 的公共对象?我说的对吗?
    • 是的,你只能访问B的公共接口,但你确实有C的行为。
    • 谢谢,但再次抱歉 Alessandro,你所说的“C 的行为”是什么意思。请给我一个小例子来说明你用内联代码所说的话。
    • 非常感谢 Alessandro,我现在明白了 :) 非常感谢你帮助我理解 :) :)
    【解决方案3】:

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

    C c = new C();
    

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

    【讨论】:

    • 谢谢 SLaks。但是 B c = new C();我不明白。
    • @Divine: 你有一个B 类型的变量引用C 类型的对象。您需要了解多态性是如何工作的。 msdn.microsoft.com/en-us/library/ms173152.aspx
    • SLaks,当然,我会阅读你提供的这个链接,非常感谢,现在我也有了一个好主意。
    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多