interface as argument or generic method with where - what is the difference?

前端 未结 4 1504
灰色年华
灰色年华 2021-01-17 11:46

Is any difference between :

public void Method1(class1 c, T obj) where T:Imyinterface

And

public void Method2(clas         


        
4条回答
  •  说谎
    说谎 (楼主)
    2021-01-17 12:25

    As noted, with void methods, there is not much difference in usage.

    If you look behind the scenes you will see that with the generic method, .NET will compile a separate method for each type you call it with. This has the effect of avoiding boxing when called with a struct.

    The big difference occurs when you use a return type.

    public T Method1(class1 c, T obj) where T: IMyInterface

    and

    public IMyinterface Method2(class1 c, IMyInterface obj)

    With the generic version, you get the original type back, so you can continue calling properties or methods (instance or extension) on the original type.

    With the non-generic version, you only get back a value of type IMyInterface, so you can only call properties or methods that are part of IMyInterface.

    This is most interesting, in my book, when used with extension methods and a fluent-style API.

    public static T Move(this T animal) where T : ICanMove
    {
        return animal;
    }
    
    public static T Fly(this T animal) where T : ICanFly
    {
        return animal;
    }
    
    public static T Pounce(this T animal) where T : ICanPounce
    {
    
        return animal;
    }
    

    Given that Tiger implements ICanMove and ICanPounce and the Eagle implements ICanMove and ICanFly, I can call the above extension methods that apply to the original type. Intellisense will show .Fly() and .Move() available for an Eagle, and .Pounce() and a .Move() for a Tiger.

    var birdie = new Eagle();
    
    birdie
        .Move()
        .Fly()
        .Move()
        .Fly();
    
    var kitty = new Tiger();
    
    kitty
        .Move()
        .Pounce()
        .Move()
        .Pounce();
    

    Here is what it would look like if you implemented Move non-generically:

    public static ICanMove Move(this ICanMove animal) 
    {
        return animal;
    }
    

    Since an ICanMove interface is returned, the compiler has no idea that it was originally an Eagle or a Tiger, and so you can only use extensions, methods, or properties that are part of the ICanMove interface.

提交回复
热议问题