donet中的new关键子大致有以下用途:
1.作为运算符,创建对象和调用构造函数
如:
class MyClass
{
private int _id;
public MyClass(int id)
{
_id = id;
}
}
struct MyStruct
{
private string _name;
public MyStruct(string name)
{
_name = name;
}
}
class NewReflecting
{
public static void Main(string[] args)
{
int i;
int j = new int();
MyClass mClass = new MyClass(123);
MyStruct mStruct = new MyStruct("My Struct");
}
}
注意new用于引用类型和值类型的操作有不同,通过ILDASM工具反汇编出来可以看出。
(1)new一个class时,new完成了以下两个方面的内容:一是调用newobj命令来为实例在托管堆中分配内存;二是调用构造函数来实现对象初始化。
(2)new一个struct时,new运算符用于调用其带构造函数,完成实例的初始化。
(3)new一个int时,new运算符用于初始化其值为0。
(4) 另外必须清楚,值类型和引用类型在分配内存时是不同的,值类型分配于线程的堆栈(stack)上,并变量本身就保存其实值,因此也不受GC的控制,;而引用类型变量,包含了指向托管堆的引用,内存分配于托管堆(managed heap)上,内存收集由GC完成。
2.作为修饰符,用于隐藏继承中基类的成员。
如:
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 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());
}
}
class Tester
{
public static void Main(string[] args)
{
Number num = new Number();
num.ShowNumber();
IntNumber intNum = new IntNumber();
intNum.ShowNumber();
Number number = new IntNumber();
number.ShowInfo();
number.ShowNumber();
}
}
}
用new操作符可以隐藏掉基类的成员ShowInfo,如果基类没用Virtual,则new可以省略,否则需要显式的用new来隐藏。
3.作为约束,用于在泛型中可能用作类型参数的参数的类型
MSDN中的定义是:new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。当泛型类创建类型的新实例时,将此约束应用于类型参数。
注意:new作为约束和其他约束共存时,必须在最后指定。
其定义方式为:
class Genericer<T> where T : new()
{
public T GetItem()
{
return new T();
}
}
实现方式:
class MyCls
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public MyCls()
{
_name = "Emma";
}
}
class MyGenericTester
{
public static void Main(string[] args)
{
Genericer<MyCls> MyGen = new Genericer<MyCls>();
Console.WriteLine(MyGen.GetItem().Name);
}
}
4.用于某些基本类型的初始化,完成一些更优越的初始化操作。