2010-11-27 25 views
3

インターフェイスを返すメソッドのコンセプトについて少し混乱します。これについて詳しく説明している記事やリファレンスはありますか?私はいつ/なぜあなたがこれをやりたいのだろうと混乱しています。そして、それが関連しているオブジェクトとの間でインターフェイスをキャストすることができます(私は正しいと思います)。あなたが行うことになっているものを何かの契約を分離したい場合にインターフェイスを返す私はなぜあなたはこれをしたいかもしれない時に/上の混乱しているC# - インターフェイスを返すメソッド

+1

私はあなたのインターフェイスを作ったが、その後、私はそれをキャスト...;)ここで –

答えて

14

は、コンクリートから、良いです実装(どのようにそれを行う)。インターフェイスを使用すると、コードをより簡単に再利用および変更できます。

IFooのインターフェイスとIFooを実装している実装がSimpleFooの場合は、インターフェイスに対してプログラムして基本的な機能を得ることができます。後で同じIFooインターフェイスも実装するAdvancedFooの実装を行うことができます。今度は新しいオブジェクトを返すだけで済み、コードの残りの部分は変更を加えることなく新しい高度なクラスを使用します。また、インタフェースを使用すると、実行時に使用するクラスを選択することもできます。

コードでインターフェイスが返されるときにも、柔軟性が向上します。あなたは現在List<T>を返すかもしれませんが、結果をIEnumerable<T>として使用する必要がある場合は、代わりにこれを返すべきです。次に、インプリメンテーションを変更して、結果がオンザフライで生成されるようにすることができます(イテレータブロックなど)。呼び出し元コードは引き続き動作します。どのように

それはあなたがインターフェースの全体のポイントは、あなたがこれを実行する必要はありませんということです

に関連付けられたオブジェクトから/へのインターフェースをキャストすることができるということです。特定の実装が何であるか心配することなくインターフェイスを使用するだけです。正しいメソッドがランタイムによって呼び出されます。あなたがキャストする必要があると思うなら、それはあなたのインターフェースがあなたのニーズをサポートするのに十分に豊かではないという兆候かもしれません。

あなたはあなたががする必要がある場合にキャストすることができます。このキャストが失敗することができますし、代わりにasを使用することが

IFoo foo = getFoo(); 
SimpleFoo simpleFoo = (SimpleFoo)foo; 

注:

IFoo foo = getFoo(); 
SimpleFoo simpleFoo = foo as SimpleFoo; 
if (simpleFoo == null) 
{ 
    // Too bad... 
} 
else 
{ 
    // Now we can use simpleFoo. 
} 
+0

は、私はインタフェースが返さ見てきた方法の例です。アプリケーションでは、Wcf経由でサーバーからデータを取得するクライアントがあります。各エンティティタイプに対して異なる 'Get'メソッドを使用する代わりに、インターフェイスを返すGetメソッドが1つあります。インタフェースには、エンティティのタイプを示すプロパティが含まれています。型に基づいて、インタフェース(オブジェクト)は適切な型にキャストされ、使用されます。 – Hosea146

+0

@ Hosea146: 'object'はインタフェースではありません。これはクラスです。私はあなたが持っているコードの中に何があるのか​​正確には分かっていませんが、実際にインターフェイスを使用している場合は、インターフェイスを使用する特に良い例のようには聞こえません。 –

+0

私たちがやっていることをよりよく説明するために、これに関する別の質問を投稿します。 – Hosea146

0

私はおよそ混乱だかわからないんだけどそれ。インタフェースは抽象クラスではなく抽象メソッドを持たず、宣言された状態(フィールド)もありません。したがって、インタフェースを返すことは、抽象基本クラスを返すようなものです。

代わりにインターフェイスを返す理由は、インターフェイスが本格的なオブジェクトではなく機能の小さなバンドルを表すからです。典型的な例では、リストの代わりにIEnumerableを返すのは、基になるオブジェクトがリストであっても、メソッドは実際には順序付けされたオブジェクトセットを返すだけで、呼び出し元はすべて参照する必要があるからです。将来、このメソッドは配列などのデータ構造体を返す可能性があります。しかし、呼び出し元がIEnumerableとみなすので、呼び出し元には関係ありません。これは、実装ではなくインターフェイスへのプログラミングという一般原則に従います。

0

メソッドはインターフェイス自体を返すことはできません。インタフェースとは、オブジェクトが実装すべきメソッドの記述です。オブジェクトに必要なメソッドのリストを返すことはできません。

あなたができることは、インターフェイスのインスタンスを返すことです。

using System.Collections.Generic; 

ICollection<int> getCollection() { 
    return new LinkedList<int>(); 
} 

このメソッドはLinkedListのインスタンスを返しますが、戻り値の型はICollectionです。つまり、LinkedListはICollectionを継承しているので、ICollectionを使用できる場所であればgetCollection()の戻り値を使用できます。戻り値の型がLinkedListの場合、LinkedListが期待される戻り値の型のみを使用でき、柔軟性が低下します。

C# interfaces tutorial

1

時にはあなたはそれを実装するクラスを返すの一般的な方法ですので、インターフェイスを返すようにしたいです。インターフェイスにあるメソッドを呼び出すことができるので、返される実際のクラスが何であるか心配する必要はありません。例えば

public interface IFooBar 
{ 
    String GetData(); 
} 

public class Foo : IFooBar 
{ 
    public String GetData() { return "Foo"; } 
} 

public class Bar : IFooBar 
{ 
    public String GetData() { return "Bar"; } 
} 

public class DataManager 
{ 
    public static IFooBar GetFooBar() 
    { 
     IFooBar foobar = ... 
     return foobar; 
    } 
} 

public class MainAppClass 
{ 
    public void SomeMethod() 
    { 
     //You don't care what type of class you get here 
     //you only care that the object you get back let's you 
     //call GetData. 
     IFooBar foobar = DataManager.GetFooBar(); 
     String data = foobar.GetData(); 
     //etc 
    } 
} 
関連する問題