7


4

ジェネリック拡張メソッドの余分なジェネリックパラメーター?

さらに別のジェネリック型(この例ではTC)をとるジェネリッククラスAの拡張メソッドを作成したいと思いますが、それは不可能だと思いますか?

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

static class Ext
{
    public static A DoIt(this A a)
    {
        return a;
    }
}

class A { }
class B { }

3 Answer


4


わずかな構文の変更を受け入れることができれば、それは可能でしょう。

それをに変更してください。

var a = new A();
a.Do().It();

秘Theは、Doメソッドが `A`の拡張メソッドであることです:

public static Doer Do(this A a)
{
    return new Doer(a);
}

秘Theは、このシグニチャで型推論を使用して、「a」からTAおよびTBをピックアップできるため、明示的に指定する必要がないことです。

Doerクラスは、必要な汎用メソッドを提供します。

public class Doer
{
    public void It() { }
}


3


いいえ、可能ですが、コンパイラに「TC」とは何かという許容可能なコンテキストを与える必要があります。 この3番目のパラメーターTCは、コード内のどこにも使用されていないため、何でもかまいません。したがって、コンパイラーは文句を言います。 ただし、タイプTCの拡張メソッドに着信パラメーターを追加すると、コンパイラーがTCの実際のタイプを推測できる状況を達成でき、呼び出し時にタイプが何であるかを示す必要さえありません。メソッド:

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

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

class A { }
class B { }

ただし、コンパイラにコンテキストを与える必要があります。

そうは言っても、汎用パラメーターを指定することは、すべてか無かの努力です。 コンパイラーは、すべてのジェネリック型パラメーターの型を推測することもできないし、推測することもできますが、そのすべてを伝える必要があります。


1


あなたは正しい、それは不可能です。 すべての型パラメーター( TA、` TB`、および TC)を指定するか、どれも指定しないでください(コンパイラーの型推論に任せてください)。

いくつかの可能性があります。

  • `DoIt`をインスタンスメソッドに変換します(ただし、作成したと思いますが) 意図的に拡張メソッド)

  • 何らかの形で「TC」を制約する別のパラメーターを「DoIt」に追加します 型推論が機能します

2番目の例については、 Enumerable.Select`を見てください。ソースと宛先の型に対して2つの型パラメーターがありますが、どちらも Select`に渡される引数から推測されます。