最近在看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是引用,改变值会生效。