两道C#面试题的思考,大家一起探讨

起源

最近小弟因为项目要被印度抢走了,去别的组进行了一次面试。有几个面试题,和大家进行探讨。
先看题大家可以先想想结果
1. string aString = "a" + "b" + "c"; 有几次内存分配;
2. 多态的考察,如下的输出结果。

Code
public class Program
    {
        
static void Main(string[] args)
        {
            A a 
= new C();
            a.Show();
            Console.ReadKey();
        }
    }
    
public class A
    {
        
public virtual void Show()
        {
            Console.WriteLine(
"A");
        }
    }
    
public class B:A
    {
        
public new virtual void Show()
        {
            Console.WriteLine(
"B");
        }
    }
    
public class C:B
    {
        
public override void Show()
        {
            Console.WriteLine(
"C");
        }
    }

 

我自己的答案如下

答案

 

 

引入和一点分析

  1. 1 第一个问题是值类型和引用类型说起的。面试的人问我关于值类型和引用类型。我blabla说了些堆栈和内存分配。我说了string是特殊的引用类型,他不可变。然后引出这个问题。string aString = "a" + "b" + "c"; 有几次内存分配。按着开始的引导。我的答案是a一次,b一次,ab一次。因为ab还是string不可变。那么abc还需要一次。具体不数是几次。面试官给我的答案也是很多次。他也是这么认为的。
    回来之后我写了这个代码。看了下IL发现不是这么回事。CLR可以直接生成字符串"abc".

  后来请教高人,多少明白是怎么个意思了。因为+的含义编译器是知道的就是编译器知道string不可变,所以提前在生成的IL代码里面写死了,写在数据段里面了,等同于写死了。如果编译器比较先进的话他能检测到aString也不需要内存。

  1. 2 看IL

  

  IL中也是非常的清楚的现实了调用的是A中的Show方法。我的理解是:

  A定义了方法show,注意B中的show方法虽然也是virtual的,但是之前有一个new。B从新定义了一个方法show。
  C 中的override的是B定义的那个方法。
  【这个时候实际上C里面有两个show方法。】这段有待於斟酌。
  出现这种情况的时候 如果通过基类调用的话 就选距离那个基类最近的方法。所以会调用A中的Show方法。

  看了回复觉得徐少侠解释的非常好!!

======================================

  回复  引用  查看  删除  
#23楼2009-08-10 14:46 | 徐少侠      
用距离基类近来解释似乎不科学

A类有虚Show

B类就已经有两个Show方法了

C也的确有两个

由于最终的变量是A类型的,因此搜索函数入口时从基类A的入口表开始,根据虚方法定义查找子类的重写方法,但是由于无法再B类定义中发现override方法
则最终调用的是A的现实
Ivony...解释同样精彩。
========================================
回复  引用  查看  删除   #27楼2009-08-10 14:56 | Ivony...      
在C的内部,你就能调用到这三个方法:

public class C : B
{
//...

public void Test()
{
((A) this).Show();
base.Show();
this.Show();
}

}
=======================================

 

Code2
    public class Program
    {
        
static void Main(string[] args)
        {
            A a 
= new C();
            a.Show();
            Console.ReadKey();
        }
    }
    
public class A
    {
        
public virtual void Show()
        {
            Console.WriteLine(
"A");
        }
    }
    
public class B:A
    {
        
public override void Show()
        {
            Console.WriteLine(
"B");
        }
    }
    
public class C:B
    {
        
public new void Show()
        {
            Console.WriteLine(
"C");
        }
    }

 


小弟新手,有什么不对的地方。欢迎大家拍砖。

 

参考文章:[你必须知道的.NET]第十七回:貌合神离:覆写和重载http://www.cnblogs.com/anytao/archive/2007/11/07/must_net_17.html

posted @ 2009-08-10 13:08  AlexLiu  阅读(6553)  评论(78编辑  收藏  举报