More Effective C# Item8 :尽可能使用泛型方法,除非需要将类型参数用于实例的字段中
2010-06-14 23:08
881 查看
我们需要来讨论一下泛型类和泛型方法的取舍。
一般情况下,我们很容易的被泛型类型的定义限制住,但是很多情况下,我们使用泛型方法就可以了。之所以推荐泛型方法,是因为当使用泛型类时,C#编译器必须根据给出的约束为整个泛型类生成合法的IL,而且给出的约束也必须满足整个类的需要;而泛型方法只需要为满足泛型方法的约束就可以了,这样我们可以在同一个类中针对不同的方法设置不同的约束,编译器根据不同的约束来匹配不同的重载形式,同时使用者也会觉得更加清晰。
来看下面的代码。
代码
执行结果很简单,在此不再赘述。
我们来看上述代码, 请注意以下语句:
上述三条语句的执行结果都是一样的,即将“B”输出到控制台中。
但是从上面语句中,我们可以看到以下两个问题:1)如果用户使用第一句或者第二句的话,还需要执行泛型类型,是比较麻烦的,相反,第三句没有对类型进行任何指定,而是由编辑器进行确定,从易用性来说,更好一些,而这种优点,只能用于泛型方法,无法用于泛型类;2)由于泛型方法可以由编译器来决定运行时采用的重载形式,那么泛型方法可以带来更好的可扩展性,例如,我们可以在UtilWithourGenerics类中追加一个静态方法:Max(string left, string right),这样,程序在执行时,上述第三句代码就会调用非泛型版本的重载形式,而不会调用泛型版本的重载形式,这种修改方式,只是在UtilWithoutGenerics类中进行,调用方式不需要进行任何改动的。这对于项目后期维护来说,是非常重要的。
虽然泛型方法有很多好处,但是在某些情况下,我们还是需要使用泛型类的,例如:1)类本身需要存放类型参数对象作为其内部状态(例如集合类型);2)类实现了泛型接口,这是类本身也必须是泛型类。
综上,使用泛型方法,和泛型类相比,有以下两点优势:1)简化了调用过程;2)提高了程序的可扩展性和可维护性。
一般情况下,我们很容易的被泛型类型的定义限制住,但是很多情况下,我们使用泛型方法就可以了。之所以推荐泛型方法,是因为当使用泛型类时,C#编译器必须根据给出的约束为整个泛型类生成合法的IL,而且给出的约束也必须满足整个类的需要;而泛型方法只需要为满足泛型方法的约束就可以了,这样我们可以在同一个类中针对不同的方法设置不同的约束,编译器根据不同的约束来匹配不同的重载形式,同时使用者也会觉得更加清晰。
来看下面的代码。
代码
private static void Test() { Console.WriteLine(UtilWithGenerics<int>.Max(1, 2)); Console.WriteLine(UtilWithGenerics<string>.Max("A", "B")); Console.WriteLine(UtilWithoutGenerics.Max(1, 2)); Console.WriteLine(UtilWithoutGenerics.Max("A", "B")); }
执行结果很简单,在此不再赘述。
我们来看上述代码, 请注意以下语句:
Console.WriteLine(UtilWithGenerics<string>.Max("A", "B")); Console.WriteLine(UtilWithoutGenerics.Max<string>("A", "B")); Console.WriteLine(UtilWithoutGenerics.Max("A", "B"));
上述三条语句的执行结果都是一样的,即将“B”输出到控制台中。
但是从上面语句中,我们可以看到以下两个问题:1)如果用户使用第一句或者第二句的话,还需要执行泛型类型,是比较麻烦的,相反,第三句没有对类型进行任何指定,而是由编辑器进行确定,从易用性来说,更好一些,而这种优点,只能用于泛型方法,无法用于泛型类;2)由于泛型方法可以由编译器来决定运行时采用的重载形式,那么泛型方法可以带来更好的可扩展性,例如,我们可以在UtilWithourGenerics类中追加一个静态方法:Max(string left, string right),这样,程序在执行时,上述第三句代码就会调用非泛型版本的重载形式,而不会调用泛型版本的重载形式,这种修改方式,只是在UtilWithoutGenerics类中进行,调用方式不需要进行任何改动的。这对于项目后期维护来说,是非常重要的。
虽然泛型方法有很多好处,但是在某些情况下,我们还是需要使用泛型类的,例如:1)类本身需要存放类型参数对象作为其内部状态(例如集合类型);2)类实现了泛型接口,这是类本身也必须是泛型类。
综上,使用泛型方法,和泛型类相比,有以下两点优势:1)简化了调用过程;2)提高了程序的可扩展性和可维护性。
相关文章推荐
- 尽可能使用泛型方法,除非需要将类型参数用于实例的字段
- More Effective C# Item6 : 使用委托定义类型参数上的方法约束
- More Effective C# Item3 : 运行时检查泛型参数的类型并提供特定的算法
- More Effective C# Item1 : 使用1.x框架API的泛型版本
- more effective c++笔记1-----Item M2:尽 量使用C++风格的类型转换
- Java获取泛型参数的类型的方法 - 实例讲解
- 读书笔记 effective c++ Item 24 如果函数的所有参数都需要类型转换,将其声明成非成员函数
- 《More Effective C++》 Item M2:尽量使用C++风格的类型转换
- 使用C#反射中的MakeGenericType函数,来为泛型方法和泛型类指定(泛型的)类型
- 使用泛型 类型“System.Collections.Generic.IEnumerator<T>”需要 1 个类型参数
- Effective Java Item2:当构造方法的参数(尤其是可选参数)比较多时使用Builder模式
- 使用泛型类型System.Collections.Generic.Icomparer &lt;T&gt; 需要一个类型参数
- Effective C# Item6:明辨值类型和引用类型的使用场合
- Unity C# 使用反射,利用字符串作为泛型参数调用泛型方法。
- C#定义泛型方法错误-类型“T”必须是引用类型才能用作泛型类型或方法“System.Data.Linq.Table<TEntity>”中的参数“TEntity”
- Sql2012如何将远程服务器数据库及表、表结构、表数据导入本地数据库 自定义日志记录功能,按日记录,很方便 C#常量和字段以及各种方法的语法总结 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法 asp.net webapi 自定义身份验证
- C#中综合使用字段,属性和方法的实例
- C#中使用where子句限制泛型方法的泛型类型
- c# 使用泛型类型作为参数
- C# 学习教程 之 泛型类型参数的限制约束和代码实例