毫无疑问,像你引用的例子一样,除了其他答案中提到的运行时执行性能之外,并没有太大的区别。
抛开通用集合的好处(例如通过避免装箱/拆箱来提高性能),我们都知道并经常使用——泛型从消费者的角度来看也非常出色。例如,下面的代码片段可以自我解释,以便从消费者的角度来看可视化API使用的灵活性:
interface IEntity
{
int Id {get;set;}
}
class Student : IEntity
{
int Id {get;set;}
string SubjectOpted {get;set;}
}
class Employee : IEntity
{
int Id {get;set;}
string DepartmentName{get;set;}
}
interface INonGenericRepository
{
IEntity Get(int id)
}
interface IGenericRepository<T> where T:Entity
{
T Get(int id)
}
class NonGenericRepository : IRepository
{
public IEntity Get(int id) {
}
class GenericRepository<T> : IRepository<T>
{
public T Get(int id) {
}
Class NonGenericStudentConsumer
{
IEntity student = new NonGenericFRepository().Get(5);
var Id = student.Id
var subject = student.SubjectOpted
}
Class GenericStudentConsumer
{
var student = new GenericFRepository<Student>().Get(5);
var Id = student.Id
var subject = student.SubjectOpted
}
使用泛型约束增加灵活性的几个其他用例有:
例如,我想确保传递给方法的参数实现了 IAdd
和 IMultiply
接口,而我有一个类实现了这两个接口,如下所示:
public class BusinessOpeartion<T> where T : IAdd, IMultiply{
void SomeBusinessOpeartion(T obj) { }
}
如果我需要采用非通用方法,我不得不创建冗余的虚假接口,例如:
interface IDummy : IAdd, IMultiply
public class BusinessOpeartion{
void SomeBusinessOpeartion(IDummy obj) { }
}
前一种方法更简洁明了吗?
在回答时,还有一件小事情突然出现。如果需要,在方法内如何获取参数类型的新实例:
你无法进行以下操作
IDummy dummy = new IDummy(); /*illegal*/
但是使用泛型,您可以这样写:
T temp = new T();
,前提是有
new()
的约束。
另外,如果您需要参数类型的默认值呢?
您无法这样做:
var default = default(IDummy); /*illegal*/
但是使用泛型,你可以这样写:
var default = default(T)
。