代码改变世界

C#面试题整理(1)

2018-01-24 11:45  星门  阅读(941)  评论(0编辑  收藏  举报

最近在看CLR VIA C#,发现了一些案例很适合来做面试题。特此整理:

1,System.Object里的GetType方法是否为虚函数?说出理由。
答案:不是,因为C#是一种类型安全的语言,如果覆写GetType,可以伪造类型,会引起很多问题。
 
2,在64位的操作系统上,C#语言定义的一个int变量,代表64位整数还是32位整数?为什么?
答案:32位,因为C#的int真实类型是System.Int32。
 
3,C#中是否存在联合的概念?如何使用?
答案:没有联合,可以用Attribute特性把struct封装成一个联合。具体用法略。
 
4,
public static void Main()
{
     Int32 v = 5;
     Object o = v;
     v = 123;
     
     Console.WriteLine(v + ", " + (Int32)o);
}
以上代码一共进行了几次装箱?
答案:3次。第一次,Object o = v;第二次,v + ", ";第三次 , 字符串+(Int32)o。String的Contact方法传入的是Object类型,所以需要装箱。
 
5,阅读以下代码,写出输出:
internal struct Point
{
     private Int32 m_x, m_y;
 
     public Point(Int32 x, Int32 y)
     {
          m_x = x;
          m_y = y;
     }
 
     public void Change(Int32 x, Int32 y)
     {
          m_x = x;
          m_y = y;
     }
 
     public override string ToString()
     {
          return String.Format("({0},{1})", m_x.ToString(), m_y.ToString());
     }
}
 
class Program
{
     static void Main(string[] args)
     {
          Point p = new Point(1, 1);
          
          Console.WriteLine(p);
 
          p.Change(2, 2);
          Console.WriteLine(p);
 
          Object o = p;
          Console.WriteLine(o);
          
          ((Point)o).Change(3,3);
          Console.WriteLine(o);
     }
}
答案:

 

,首先Point是值类型,其次,WriteLine方法并没有关于Point的重载方法(毕竟使我们自己写的)。因此,我们第一个WriteLine会把p进行装箱,调用WriteLine(Object)这个方法。装箱后的p找到有覆写的ToString,因此可以正常调用,这样前三次的输出应该都没有问题。最后一次输出,o是已装箱的p,我们强制转换成Point,这里会有一个拆箱的过程,系统会存一个临时的值变量Point,这个临时值变量会去调用Change方法,注意这并不会影响引用类型o的值。所以依然是2,2。
 
6,此题是5的加强版,请看代码:
internal interface IChangeBoxedPoint
{
     void Change(Int32 x, Int32 y);
}
 
internal struct Point : IChangeBoxedPoint
{
     private Int32 m_x, m_y;
 
     public Point(Int32 x, Int32 y)
     {
          m_x = x;
          m_y = y;
     }
 
     public void Change(Int32 x, Int32 y)
     {
          m_x = x;
          m_y = y;
     }
 
     public override string ToString()
     {
          return String.Format("({0},{1})", m_x.ToString(), m_y.ToString());
     }
}
 
class Program
{
     static void Main(string[] args)
     {
          Point p = new Point(1, 1);
 
          Console.WriteLine(p);
 
          p.Change(2, 2);
          Console.WriteLine(p);
 
          Object o = p;
          Console.WriteLine(o);
 
          ((Point)o).Change(3,3);
          Console.WriteLine(o);
 
          ((IChangeBoxedPoint)p).Change(4,4);
          Console.WriteLine(p);
 
          ((IChangeBoxedPoint)o).Change(5,5);
          Console.WriteLine(o);
     }
}
答案:

 

,虽然结构体继承了interface,但它的本质还是值类型,因此前面四个输出和题5一毛一样。第五个输出同第四个,值改变的是装箱后的p,因此值类型p的输出不受影响。最后一个输出,o已经是装箱后的对象,因此o是引用,改变值会生效。