Extra generic parameter in generic extension methods?

落爺英雄遲暮 提交于 2020-07-04 13:22:06

问题


I would like make an extension method for the generic class A which takes yet another generictype (in this example TC), but i guess that aint possible?

class Program
{
    static void Main(string[] args)
    {
        var a = new A<B, B>();
        a.DoIt<B>();
    }
}

static class Ext
{
    public static A<TA, TB> DoIt<TA, TB, TC>(this A<TA, TB> a)
    {
        return a;
    }
}

class A<TA, TB> { }
class B { }

回答1:


If you can accept a slight syntax change, then it would be possible.

Change it to:

var a = new A<B, B>(); 
a.Do().It<B>(); 

The trick is that the Do method is an extension method on A<TA, TB>:

public static Doer<TA, TB> Do<TA, TB>(this A<TA, TB> a)
{
    return new Doer<TA, TB>(a);
}

The trick is that this signature lets type inferincing pick up TA and TB from a so that you don't have to specify them explicitly.

The Doer class provides the generic method you need:

public class Doer<TA, TB>
{
    public void It<TC>() { }
}



回答2:


No, it's possible, but you have to give the compiler some acceptable context of what "TC" is. That third parameter, TC, isn't used anywhere else in your code, so it could be anything, therefore, the compiler complains. If you add an incoming parameter to your extension method of the type TC, however, you can accomplish a situation where the compiler can infer the actual type of TC, and then you don't even have to indicate what the types are when you call the method:

class Program
{
    static void Main(string[] args)
    {
        var a = new A<B, B>();
        string tc = "Hi!";
        a.DoIt(tc);
    }
}

static class Ext
{
    public static A<TA, TB> DoIt<TA, TB, TC>(this A<TA, TB> a, TC c)
    {
        return a;
    }
}

class A<TA, TB> { }
class B { }

But you have to give the compiler some context.

That being said, specifying generic parameters is an all-or-nothing endeavor. Either the compiler can infer the types of every generic type parameter, or it can't, and you have to tell it what all of them are.




回答3:


You're right, it's not possible. You have to either specify all type parameters (TA, TB and TC), or none of them (and leave it up to the compiler's type inference).

A couple of possibilities:

  • Turn DoIt into an instance method (although I guess you've made it an extension method on purpose)
  • Add another parameter to DoIt that somehow constrains TC, meaning type inference will work

For an example of the second one, look at Enumerable.Select: it has two type parameters, for the source and destination types, but they're both inferred from the arguments passed to Select.



来源:https://stackoverflow.com/questions/2345140/extra-generic-parameter-in-generic-extension-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!