2013-03-12 1 views
5

排他的と思われる異なる制約を持つメソッドのオーバーロードで問題が発生しました。これは私の例です:同じシグネチャのメンバーが異なる型制約ですでに定義されています

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

答えて

8

それはコンパイラの制限はありません - それは言語の限界だ(そして恐らくCLRをだけでなく、私はよく分かりません)。

これらは根本的に重複しています。つまり、リターンタイプでオーバーロードしようとするようなものです。それはサポートされていません。それ

は、これらの呼び出しは、すべての異なるメソッドの呼び出しにコンパイルするようなメソッドを宣言する可能です:

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

を...しかし、それは常にオプションのパラメータおよび/またはパラメータ配列を含み、そしてそれはhorribleをです。

public void Foo() {} 
public void Foo<T>() {} 
public void Foo<T1, T2>() {} 
+0

を、少なくとも私はこれら2つの制約が排他的であることを言って正しかったと、それだけで限界だことを願っています、 右? :) –

+0

@IlyaChernomordik:それは限界ですが、かなり合理的なIMOです。 –

+0

これを許可すると何が問題になりますか?私はそれがクラスかどうか(私はそれがnullであるかどうかをチェックすることができます)、それはちょうど(私はその価値があることを知っている)長いですかどうかに応じて別のアクションを行う必要があります。だから、方法は、それが思われるメソッドに異なる名前を付けるだけでよいはずです。私は間違いなく恐ろしい方法を使用したくありません:) –

2

あなたはvaringでメソッドをオーバーロードすることはできません。

はまた、あなたが一般的な制約によってオーバーロードすることはできませんが、あなたは、一般的な「アリティ」(型パラメータの数)によってオーバーロードできることに注意してくださいジェネリックパラメータcontainsts有効なメソッドオーバーロードの場合、メソッドに対して異なる入力パラメーターが必要です。

1

コンパイル時にどちらの方法には、次の名前を持つ必要があります

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 { 

    } 
} 
関連する問題