代码之家  ›  专栏  ›  技术社区  ›  Pierre-Alain Vigeant

使用泛型where子句调用比使用非泛型调用有什么好处?

  •  6
  • Pierre-Alain Vigeant  · 技术社区  · 14 年前

    我见过一些例子,他们把一个电话

    void Add(IDrawing item);
    

    进入之内

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

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

    为了回答Jon Skeet,我们的程序员使用的代码是:

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

    我不认为这里使用泛型而不仅仅使用 IDrawing 类型。我想一定有什么情况是很合适的。我很好奇,想看看我是否遗漏了什么。

    3 回复  |  直到 14 年前
        1
  •  5
  •   Jon Skeet    14 年前

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

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

    现在你不会想接受 IList<IDrawing> 这里-因为如果你有一个 List<Painting> TDrawing 成为 Painting :约束确保属性可用于 if 条件,并且它是泛型的事实允许您安全地将该项添加到列表中。

    满的 你认为没有好处的例子,值得具体介绍一下。

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

        2
  •  1
  •   BFree    14 年前

    想想这个场景:

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

    现在在编译时调用此方法时,您将能够访问特定 TDrawing 传入此方法以与 Func

    Add<MyDrawing>(drawing, m => m.SomeMyDrawingProp);
    
        3
  •  0
  •   supercat    13 年前

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