您的位置:首页 > 编程语言 > C#

C#中的where泛型约束中的new()使用(转)

2016-06-17 17:03 543 查看
在MSDN上面对new()解释说到是where字句的构造函数约束,带有new()约束的任何类型都必须有可访问的无参构造函数,正常来说C#创建的类默认都有一个无参的构造函数,即使你没有写,但是如果你写了一个有参数的构造函数后,那么就没有默认无参的那个了,就需要自己手动写一个。

还是拿前两天的国籍那个举个例子:

1
2
3
4
5
6
7
8
9
10
11

/// <summary>
/// 国籍的接口
/// </summary>
public interface INationality
{
string Nationality
{
set;
}
string GetNationality();
}

国籍的接口不用改变还是这个,继承此接口的类稍微修改了一下,为每个类增加一个构造方法,改造如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

/// <summary>
/// 中国人
/// </summary>
public class Chinese : INationality
{
public Chinese(string DefaultNationality)
{
_Nationality = DefaultNationality;
}
private string _Nationality;
public string Nationality
{
set
{
_Nationality = value;
}
}

public string GetNationality()
{
return string.IsNullOrEmpty(_Nationality) ? "Chinese." : _Nationality;
}
}

/// <summary>
/// 美国人
/// </summary>
public class American : INationality
{
public American(string DefaultNationality)
{
_Nationality = DefaultNationality;
}
private string _Nationality;
public string Nationality
{
set { _Nationality = value; }
}

public string GetNationality()
{
return string.IsNullOrEmpty(_Nationality) ? "American." : _Nationality;
}
}

其实变动也不大,泛型类也没有修改,但是会报错,在创建实例化对象的地方,如下:

1
2
3
4
5
6
7
8
9
10
11
12

/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
public class PrintNationality<T> where T : INationality, new()//由于此处有new()的约束,所以编译器编译的时候无法通过,那么就将new()去掉,或者为继承INationality的类增加public类型的无参构造函数
{
//T item = new T(); 在这个地方就不能创建实例化对象了,会提示错误“必须有具有公共无参构造函数的非抽象类型,才能用作泛型类型或方法"xxxx"中的参数T”
public void Print()
{
//Console.WriteLine(string.Format("Nationality:{0}", item.GetNationality()));
}
}

要解决上面的问题,就是给继承INationality的接口的每个类都增加一个无参的public型的构造方法,或者,将派生类后面的new()去掉。这样的话,当实例化泛型类的时候就不会有问题了。

上面写那么多也是举一个小例子,其实MSDN说的很明白,就是where字句后面有new()约束的话,T类型必须有公有的无参的构造函数。

又一篇相关文章:

对于new()约束,大家可能有一个误解,以为使用了new约束之后,在创建对象时与非泛型的版本是一致的:
public class Tester<T> where T:new()

{

public Tester()

{

  t = new T();//等同于非泛型版本的new? 例如 object o = new object();?

}

private T t;

}
事实上,使用new关键字的作用只是让编译器在泛型实例化之处,检查所绑定的泛型参数T是否具有公共无参构造函数(public 无参构造函数):

Tester<SomeType> t = new Tester<SomeType>(); //此处编译器会检查SomeType是否具有无参构造函数。若没有则会有compile error。

而Tester<T>类的构造函数中的new代码,实际上等同于下面的代码:
public class Tester<T> where T:new()

{

public Tester()

{  

t = System.Activator.CreateInstance<T>();

}

private T t;

}
也就是说,仍然是用反射机制来获取泛型对象的实例的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: