7

排他的と思われるさまざまな制約を持つメソッドのオーバーロードに関する問題に遭遇しました。それが私の例です:

public class A
{
    public void Do<T>() where T : class
    {

    }

    public void Do<T>() where T : struct 
    {

    }
}

そして、これは次のエラー「同じ署名を持つメンバーが既に定義されています」でコンパイルされません。両方の条件を同時に満たすことは可能ですか、それとも C# コンパイラの制限ですか?

4

3 に答える 3

10

これはコンパイラの制限ではありません- それは言語の制限です(そしておそらく CLR も同様です。よくわかりません)。

基本的に、これらは衝突するオーバーロードです。戻り値の型でオーバーロードしようとしているようなものです。サポートされていません。

これらの呼び出しがすべて異なるメソッドの呼び出しにコンパイルされるように、メソッドを宣言することができます。

a.Do<int>();
a.Do<string>();
a.Do<int?>();

...しかし、常にオプションのパラメーターおよび/またはパラメーター配列が含まれており、恐ろしい.

また、一般的な制約によってオーバーロードすることはできませんが、一般的な「アリティ」(型パラメーターの数) によってオーバーロードできることに注意してください。

public void Foo() {}
public void Foo<T>() {}
public void Foo<T1, T2>() {}
于 2013-03-12T16:42:08.737 に答える
2

ジェネリック パラメーターの内容を変化させてメソッドをオーバーロードすることはできません。メソッドのオーバーロードを有効にするには、メソッドに異なる入力パラメーターを指定する必要があります。

于 2013-03-12T16:42:12.483 に答える
2

両方のメソッドは、コンパイル時に次の名前を持つ必要があります。

A.Do``1

ジェネリック パラメーターの数は、メソッドまたはクラスの名前になります。

あなたの状況が何であるかはわかりませんが、それらのメソッドを呼び出すためにリフレクションを利用する必要があるかもしれません:

public class A
{
    public void Do<T>()
    {
        if(typeof(T).IsValueType){
            // nasty reflection to call DoValueType
        }
        else {
            // nasty reflection to call DoReferenceType
        }
    }
    private void DoReferenceType<T>() where T : class {

    }
    private void DoValueType<T>() where T : struct {

    }
}
于 2013-03-12T16:50:34.793 に答える