①做运算符
用于创建对象和调用构造函数,小栗子a如下:
Class1 obj = new Class1();
创建匿名类型的实例,小栗子b如下:
var query = from cust in customers select new {Name = cust.Name, Address = cust.PrimaryAddress};
用于调用值类型的默认构造函数,小栗子c如下: 其中 i 初始化为 0,它是 int 类型的默认值。该语句的效果等同于:int i=0;
int i = new int();
为结构声明默认的构造函数是错误的,因为每一个值类型都隐式具有一个公共的默认构造函数。可以在结构类型上声明参数化构造函数以设置其初始值,但是,只有在需要默认值之外的值时才必须这样做。
值类型对象(例如结构)是在堆栈上创建的,而引用类型对象(例如类)是在堆上创建的。两种类型的对象都是自动销毁的,但是,基于值类型的对象是在超出范围时销毁,而基于引用类型的对象则是在对该对象的最后一个引用被移除之后在某个不确定的时间销毁。对于占用固定资源(例如大量内存、文件句柄或网络连接)的引用类型,有时需要使用确定性终止以确保对象被尽快销毁。new运算符不可以重载.
②做修饰符,用于向基类成员隐藏继承成员
作为修饰符,基本的规则可以总结为:实现派生类中隐藏方法,则基类方法必须定义为virtual;new作为修饰符,实现隐藏基类成员时,不可和 override共存,原因是这两者语义相斥:new用于实现创建一个新成员,同时隐藏基类的同名成员;而override用于实现对基类成员的扩展。
小栗子b如下:
class Number { public static int i = 123; public void ShowInfo() { Console.WriteLine("base class---"); } public virtual void ShowNumber() { Console.WriteLine(i.ToString()); } } class IntNumber : Number { new public static int i = 456; public new virtual void ShowInfo() { Console.WriteLine("Derived class---"); } public override void ShowNumber() { Console.WriteLine("Base number is {0}", Number.i.ToString()); Console.WriteLine("New number is {0}", i.ToString()); } } static void Main(string[] args) { Number num = new Number(); num.ShowNumber(); //123 IntNumber intNum = new IntNumber(); intNum.ShowNumber(); //123 456 Number number = new IntNumber(); //究竟调用了谁? number.ShowInfo(); //base class--- //究竟调用了谁? number.ShowNumber(); //派生类里面重写了ShowNumber(), 所以输出的是: 123 456 Console.ReadKey(); }
运算结果:
③作为约束
new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。如果要使用 new 约束,则该类型不能为抽象类型。当与其他约束一起使用时,new() 约束必须最后指定.