前几天去家公司面试,有一道这样的题:写出c#中new关键字的三种用法,思前想后挖空心思也只想出了两种用法,回来查了下msdn,还真是有第三种用法:用于在泛型声明中约束可能用作类型参数的参数的类型,这是在Framework 2.0 中定义泛行时才会使用到的,自己对c# 2.0 中的支持还只是粗通皮毛,怪不得累死so many脑细胞也没能想不出这第三种来!
三种用法如下: 在 C# 中,new 关键字可用作运算符、修饰符或约束。 1)new 运算符:用于创建对象和调用构造函数。这种大家都比较熟悉,没什么好说的了。 2)new 修饰符:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。 3)new 约束:用于在泛型声明中约束可能用作类型参数的参数的类型。 关于第二种用法看下例: using System; namespace ConsoleApplication1 { public class BaseA { public int x = 1; public void Invoke() { Console.WriteLine(x.ToString()); } public int TrueValue { get { return x; } set { x = value; } } } public class DerivedB : BaseA { new public int x = 2; new public void Invoke() { Console.WriteLine(x.ToString()); } new public int TrueValue { get { return x; } set { x = value; } } } class Test { static void Main(string[] args) { DerivedB b = new DerivedB(); b.Invoke();//调用DerivedB的Invoke方法,输出:2 Console.WriteLine(b.x.ToString());//输出DerivedB的成员x值:2 BaseA a = b; a.Invoke();//调用BaseA的Invoke方法,输出:1 a.TrueValue = 3;//调用BaseA的属性TrueValue,修改BaseA的成员x的值 Console.WriteLine(a.x.ToString());//输出BaseA的成员x的值:3 Console.WriteLine(b.TrueValue.ToString());//输出DerivedB的成员x的值,仍然是:1 //可见,要想访问被隐藏的基类的成员变量、属性或方法,办法就是将子类造型为父类,然 //后通过基类访问被隐藏的成员变量、属性或方法。 } } } new约束指定泛型类声明中的任何类型参数都必须具有公共的无参数构造函数.请看下例: using System; using System.Collections.Generic; namespace ConsoleApplication2 { public class Employee { private string name; private int id; public Employee() { name = "Temp"; id = 0; } public Employee(string s, int i) { name = s; id = i; } public string Name { get { return name; } set { name = value; } } public int ID { get { return id; } set { id = value; } } } class ItemFactory<T> where T : new() { public T GetNewItem() { return new T(); } } public class Test { public static void Main() { ItemFactory<Employee> EmployeeFactory = new ItemFactory<Employee>(); ////此处编译器会检查Employee是否具有公有的无参构造函数。 //若没有则会有The Employee must have a public parameterless constructor 错误。 Console.WriteLine("{0}'ID is {1}.", EmployeeFactory.GetNewItem().Name, EmployeeFactory.GetNewItem().ID); } } }