使用generics-where-clause调用非泛型调用有什么好处?

时间:2010-06-30 18:35:47

标签: c# generics

我见过一些例子,他们改变了像

这样的电话
void Add(IDrawing item);

void Add<TDrawing>(TDrawing item) where TDrawing : IDrawing;

除了在调用函数时欺骗intellisense显示类的名称而不是接口名称时,由于C#4中的推断类型用法,使用第二种方法还有其他优势吗?

要回答Jon Skeet,程序员使用的代码是:

public ObservableCollection<IDrawing> Items { get; private set; }

public void Add<TDrawing>(TDrawing item) where TDrawing : IDrawing
{
   this.Items.Add(item);
}

我认为使用泛型而不是仅仅使用IDrawing类型的参数没有任何优势。我认为必须有一些非常合适的案例。我很想知道我是否遗漏了什么。

3 个答案:

答案 0 :(得分:5)

这实际上取决于实施中其他地方的情况。这是一个不同的例子:

void Add<TDrawing>(TDrawing item, IList<TDrawing> list)
    where TDrawing : IDrawing
{
    if (item.SomePropertyOfIDrawing)
    {
        list.Add(item);
    }
}

现在你不想在这里使用IList<IDrawing> - 因为如果你有一个List<Painting>就不能使用它...而对于上面的通用版本,它绝对是TDrawingPainting时很好:约束确保该属性可用于if条件,并且它的通用性允许您将项目安全地添加到列表中。

如果你有完整的例子,你认为没有任何好处,那么值得特别提出。

编辑:不,在现在给出的确切示例中,将其作为通用方法没有任何优势。

答案 1 :(得分:1)

想一想这个场景:

void Add<TDrawing>(TDrawing item, Func<TDrawing, bool> func)
{
   //implementation
}

现在,在编译时,在编译时,您将能够访问传递给此方法的特定TDrawing的特定属性,以便与Func一起使用。

Add<MyDrawing>(drawing, m => m.SomeMyDrawingProp);

答案 2 :(得分:0)

带有“where”子句的版本的语义可能与没有将struct作为参数传递的版本有很大不同。接口类型的存储位置(包括参数)包含堆对象引用。类型强制实现接口到该接口类型的存储位置的结构将创建一个具有与结构相同的字段和方法的新堆对象,将所有字段内容(公共和私有)复制到该新对象,然后存储存储位置中对该对象的引用。相反,将结构体复制到该结构类型的另一个存储位置将复制所有字段(公共和私有),但将结果保留为结构,而不是堆对象。