开发者

What are the advantage of using a generics-where-clause call over a non-generic call?

I've seen some examples where they transformed a call like

void Add(IDrawing item);

into

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

Beside tricking the intellisense into displaying the name of your class instead of the interface name when calling the function, because of inferred type usage in C#4, are there any other advantage to using the second approach?

To answer Jon Skeet, the code our programmer used is:

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

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

I don't see any advantage here for using a generic instead of just using a parameter of the IDrawing type. I presume there must be some case where its very appropriate. I was curious to see if I was missing s开发者_StackOverflow社区omething.


It really depends on what's going on elsewhere in the implementation. Here's a different example:

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

Now you wouldn't want to take an IList<IDrawing> here - because then you couldn't use it if you had a List<Painting> for example... whereas with the generic version above, it's absolutely fine for TDrawing to be Painting: the constraint ensures that property is available for the if condition, and the fact that it's generic allows you to safely add the item to the list.

If you have full examples where you don't think there's a benefit, it would be worth presenting those specifically.

EDIT: No, in the exact example now given there's no advantage in making it a generic method.


Think of this scenario:

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

Now when calling this method, at compile time, you'll be able to access the specific proeprties of the specific TDrawing being passed into this method to use with the Func.

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


The semantics of the version with the "where" clause can be very different from those without when a struct is passed as a parameter. Storage locations (including parameters) of interface types hold heap object references. Type-coercing a struct which implements an interface to a storage location of that interface type will create a new heap object with the same fields and methods as the struct, copy all field contents (public and private) to that new object, and then store a reference to that object in the storage location. By contrast, copying a struct to another storage location of that struct type will copy all the fields (public and private) but leave the result as a struct, rather than a heap object.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜