读:[你必须知道的.NET] 第五回:深入浅出关键字---把new说透
一般说来,new关键字在.NET中用于以下几个场合,这是MSDN的典型解释:
- 作为运算符, 用于创建对象和调用构造函数。
本文的重点内容,本文在下一节来重点考虑。
- 作为修饰符,用于向基类成员隐藏继承成员。
作为修饰符,基本的规则可以总结为:实现派生类中隐藏方法,则基类方法必须定义为virtual;new作为修饰符,实现隐藏基类成员时,不可和override共存,原因是这两者语义相斥:new用于实现创建一个新成员,同时隐藏基类的同名成员;而override用于实现对基类成员的扩展。
另外,如果在子类中隐藏了基类的数据成员,那么对基类原数据成员的访问,可以通过base修饰符来完成。
- 作为约束,用于在泛型声明中约束可能用作类型参数的参数的类型。
MSDN中的定义是:new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。当泛型类创建类型的新实例时,将此约束应用于类型参数。注意:new作为约束和其他约束共存时,必须在最后指定。
- 使用new实现多态。 这不是我熟悉的话题,详细的内容可以参见 《多态与 new [C#]》,这里有较详细的论述
1 不断的学习代码;
2 经常看看IL语言的运行细节,对于提供.NET的认识非常有效。
- new一个class时,new完成了以下两个方面的内容:一是调用newobj命令来为实例在托管堆中分配内存;二是调用构造函数来实现对象初始化。
- new一个struct时,new运算符用于调用其带构造函数,完成实例的初始化。
- new一个int时,new运算符用于初始化其值为0。
- 另外必须清楚,值类型和引用类型在分配内存时是不同的,值类型分配于线程的堆栈(stack)上,并变量本身就保存其实值,因此也不受GC的控制,;而引用类型变量,包含了指向托管堆的引用,内存分配于托管堆(managed heap)上,内存收集由GC完成。
另外还有以下规则要多加注意:
- new运算符不可重载。
- new分配内存失败,将引发OutOfMemoryException异常。
对于基本类型来说,使用new操作符来进行初始化的好处是,某些构造函数可以完成更优越的初始化操作,而避免了不高明的选择,
1 /*
2 * Created by BpLoveGcy.cnblogs.com
3 * Gump Yin
4 * Date: 2010-3-30
5 * Time: 13:16
6 *
7 * Version:
8 * CopyRight:http://BpLoveGcy.cnblogs.com/
9 */
10
11 using System;
12 using NUnit.Framework;
13 using System.Collections.Generic;
14
15 namespace MustKnownDotNet
16 {
17 class Person
18 {
19 public Person(int age)
20 {
21 this.age = age;
22 }
23 /// <summary>
24 /// 0 not known
25 /// 1 man
26 /// 2 woman
27 /// </summary>
28 /// <returns></returns>
29 public virtual int Gender()
30 {
31 return 0;
32 }
33
34 protected int age;
35 public int Age()
36 {
37 return age;
38 }
39 }
40 class Man : Person
41 {
42 public Man(int age)
43 : base(age)
44 { }
45
46 public override int Gender()
47 {
48 return 1;
49 }
50
51 public new int Age()
52 {
53 return base.age + 2;
54 }
55 }
56 class Woman : Person
57 {
58 public Woman(int age)
59 : base(age)
60 { }
61
62 public override int Gender()
63 {
64 return 2;
65 }
66
67 public new int Age()
68 {
69 return base.age - 2;
70 }
71 }
72
73 public class SingleList<T> where T : new()
74 {
75 public T AddNewItem()
76 {
77 return new T();
78 }
79 }
80
81 [TestFixture]
82 public class New_Test
83 {
84 [Test]
85 public void TestMethod()
86 {
87 Person p = new Man(30);
88
89 Assert.AreEqual(1, p.Gender());
90 Assert.AreEqual(30, p.Age());
91 Assert.AreEqual(30 + 2, ((Man)p).Age());
92 }
93
94 [Test]
95 public void TestMethod1()
96 {
97 Person p = new Woman(30);
98 Assert.AreEqual(2, p.Gender());
99 Assert.AreEqual(30, p.Age());
100 Assert.AreEqual(30 - 2, ((Woman)p).Age());
101 }
102 [Test]
103 public void TestMethod2()
104 {
105 Person p = new Person(30);
106
107 Assert.AreEqual(30, p.Age());
108 Assert.AreEqual(0, p.Gender());
109 }
110 [Test]
111 public void TestMethod3()
112 {
113 string str = new string('*', 100);
114 // Console.WriteLine(str);
115 // instead of the following
116 string a = "****************************************************************************************************";
117
118 Assert.AreEqual(str , a);
119 }
120 }
121 }
122
3 * Gump Yin
4 * Date: 2010-3-30
5 * Time: 13:16
6 *
7 * Version:
8 * CopyRight:http://BpLoveGcy.cnblogs.com/
9 */
10
11 using System;
12 using NUnit.Framework;
13 using System.Collections.Generic;
14
15 namespace MustKnownDotNet
16 {
17 class Person
18 {
19 public Person(int age)
20 {
21 this.age = age;
22 }
23 /// <summary>
24 /// 0 not known
25 /// 1 man
26 /// 2 woman
27 /// </summary>
28 /// <returns></returns>
29 public virtual int Gender()
30 {
31 return 0;
32 }
33
34 protected int age;
35 public int Age()
36 {
37 return age;
38 }
39 }
40 class Man : Person
41 {
42 public Man(int age)
43 : base(age)
44 { }
45
46 public override int Gender()
47 {
48 return 1;
49 }
50
51 public new int Age()
52 {
53 return base.age + 2;
54 }
55 }
56 class Woman : Person
57 {
58 public Woman(int age)
59 : base(age)
60 { }
61
62 public override int Gender()
63 {
64 return 2;
65 }
66
67 public new int Age()
68 {
69 return base.age - 2;
70 }
71 }
72
73 public class SingleList<T> where T : new()
74 {
75 public T AddNewItem()
76 {
77 return new T();
78 }
79 }
80
81 [TestFixture]
82 public class New_Test
83 {
84 [Test]
85 public void TestMethod()
86 {
87 Person p = new Man(30);
88
89 Assert.AreEqual(1, p.Gender());
90 Assert.AreEqual(30, p.Age());
91 Assert.AreEqual(30 + 2, ((Man)p).Age());
92 }
93
94 [Test]
95 public void TestMethod1()
96 {
97 Person p = new Woman(30);
98 Assert.AreEqual(2, p.Gender());
99 Assert.AreEqual(30, p.Age());
100 Assert.AreEqual(30 - 2, ((Woman)p).Age());
101 }
102 [Test]
103 public void TestMethod2()
104 {
105 Person p = new Person(30);
106
107 Assert.AreEqual(30, p.Age());
108 Assert.AreEqual(0, p.Gender());
109 }
110 [Test]
111 public void TestMethod3()
112 {
113 string str = new string('*', 100);
114 // Console.WriteLine(str);
115 // instead of the following
116 string a = "****************************************************************************************************";
117
118 Assert.AreEqual(str , a);
119 }
120 }
121 }
122
ref:http://www.cnblogs.com/anytao/archive/2007/04/28/must_net_05.html