2017-01-28 36 views
1

2つのメソッドが同じ名前であるが、戻り値の型が異なる場合。それらは2つのインタフェースからのクラスによって継承されます。このクラスは、インプリメンテーションの戻り値の型が両方のインタフェースの戻り値の型に一致する場合、両方に対して1つのインプリメンテーションを提供できます。2つの異なるインターフェイスで2つのメソッドに同じ名前がありますが、実装が1つではありませんか?

たとえば、Stringタイプは、両方のメソッド:IEnumerableIEnumerable<char>を実装します。 Stringタイプの実装には、GetEnumeratorの実装が1つだけ含まれています。

私は場合

interface Ia { IEnumerator o();} 
interface Ib { IEnumerator<int> o();} 
class e : IEnumerator, IEnumerator<int>{} 
class c : Ia, Ib { public e o() { return new e(); } } 

、しかし、以下の私のアプリケーションで同様のコードは私にコンパイルエラーを与えるCharEnumeratorは両方IEnumeratorIEnumerator<char>

public CharEnumerator: IEnumerator, IEnumerator<char> 

を実装しているため、これは可能であると考えてい

public CharEnumerator GetEnumerator(); 

Visual StudioでString型のF12を実行すると、次のようなものが表示されます。 enter image description hereあなたが見ることができるように

、暗黙のうちにがIEnumerableまたはIEnumerable<char>を実装していませんGetEnumerator()の唯一の1暗黙の実装、そこ

+2

interface IFoo { IFoo Frob(); } interface IBar { IBar Frob(); } public class Blah: IFoo, IBar { Foo IFoo.Frob() => new Foo(); Bar IBar.Frob() => new Bar(); void Frob(); } 

そして今、あなたは次の動作を取得します。これは、Stringクラスが* 2 * GetEnumerator()メソッドを持っている理由です。 2番目の方法は、あいまいさを避けるために必要な明示的な実装方法です。なぜ2つも必要なのです。 –

+0

@ HansPassant私は両方の*インターフェースが明示的に実装されていると思います。 'string.GetEnumerator'は実際には2つのインタフェース規約のいずれにも準拠しない' CharEnumerator'を返します。私はこれがC#1のレガシーコードだと推測しています – InBetween

+0

@HansPassantなぜコードがコンパイルに失敗しますか? 'e'型は 'IEnumerable'と' IEnumerable <> 'から派生します – EagerToLearn

答えて

2

文字列明示的な実装があります。それは明示的に行われます。つまり、IEnumerableまたはIEnumerable<char>の参照を介してのみメソッドにアクセスできます。

戻り型がIEnumerator又はIEnumerator<T>ないのでどちらインタフェースを実装CharEnumerator GetEnumerator()方法。 CharEnumeratorのいずれかが可能ですがIEnumeratorですが、インターフェイスでと入力してください。IEnumeratorです。

明示的なインターフェイスは非常に便利です。提供している機能の1つに遭遇しました。同じ名前のメソッドを定義する1つのクラスの異なるインターフェースで実装する:C#言語は、戻り値の型の共同分散をサポートしていません

var b = new Blah(); 
b.Frob(); //returns nothing, this method is not implementing any of the two interfaces. 
(b as IBar).Frob(); //returns a bar 
(b as IFoo).Frob(); //returns a foo 
+0

上記の編集された質問をご覧ください。 Visual Studioでは、GetEnumerator()の暗黙の実装が1つだけ表示されます。 – EagerToLearn

+0

@EagerToLearnいいえ、暗黙の実装ではありません。 'CharEnumerator GetEnumerator()'は* any *インタフェースを実装していません。同様の状況を見るために私の例の編集を参照してください。明示的な実装は、型定義を検査するときは表示されません。 – InBetween

+0

したがって、stringは 'IEnumerable'と' IEumerable 'の2つの明示的な実装に加えて、' CharEnumerator GetEnumerator() 'を提供します。しかし、単に 'IEnumerable.GetEnumerator()'を明示的にするのではなく、 'IEnumerable .GetEnumerator()'を利用できるようにするのはなぜですか? – EagerToLearn

関連する問題