2010-11-28 50 views
1

インターフェイスの周りに頭を下げるのに問題があります。これは、その後、私の部分クラス内に実装されてインターフェイスメソッド戻り値の型は、インターフェイスを実装するクラスです。

public interface IData<T> 
{ 
    IData<T> Select(int id); 
    List<T> SelectMultiple(); 
    void Insert(); 
    void Update(); 
    void Delete(); 
} 

public partial class Post : IData<Post> 
{ 
    public IData<Post> Select(int id) 
    { 
     MyDataContext dc = MyDataContext.Create(); 
     return dc.Posts.Single(p => p.PostID == id); 
    } 

    public List<Post> SelectMultiple() 
    { 
     MyDataContext dc = MyDataContext.Create(); 
     return dc.Posts.ToList(); 
    } 

    // Update() and Delete() declarations 
} 
ここで同様の質問を通してトロール後、私はすべての私のクラスのために必要なCRUD操作を定義するために、次のインターフェイスを作ってみました

Post p = new Post().Select(1); 

それはでき暗黙的conveないで失敗します。

これは、すべては私がポストセレクト()メソッドを使用しようとただした場合、罰金コンパイルrtは 'IData'を 'Post'にタイプします。明示的な変換があります(キャストが欠けていますか?)

これは意味がありますが、キャストは不要ですか?私は選択がポストを返すようにしたい(ただし、ポストをインターフェースレベルでの戻り値の型として定義しない)。私はインターフェイスを誤解したのですか、それとも私ができる簡単な変更がありますか?

+0

あなたの 'Post'は懸念を混ぜているようです。 CRUDを実行し、投稿を保持します。私はそれを2つのクラスに分割します。 'Post'と' PostStorage'です。 – strager

+0

投稿はSQL Serverに格納され、LinqToSQL DBMLを介してアクセスされます。上記のPostクラスは、DBML内のPostの部分クラスです。 – Lazlow

答えて

8

あなたは(少なくとも私はあなたがそうでなければList<IData<T>>を返すだろうと、これは、あなたが望むものであると思います)これだけの署名を変更する、タイプT、ないIData<T>の何かを返したいですappropiatelyそれは:

:あなただけPostクラスでこの動作が必要な場合

public Post Select(int id) 
{ 
    MyDataContext dc = MyDataContext.Create(); 
    return dc.Posts.Single(p => p.PostID == id); 
} 

、明示的IData<T>インタフェースを実装します

public partial class Post : IData<Post> 
{ 
    public Post Select(int id) 
    { 
     MyDataContext dc = MyDataContext.Create(); 
     return dc.Posts.Single(p => p.PostID == id); 
    } 

    IData<Post> IData<Post>.Select(int id) 
    { 
     return Select(id); 
    } 

} 
+0

完璧、ありがとう - それは動作します。 – Lazlow

3

Postインスタンスを返すメソッドを変更してから、インターフェイスを返す明示的なインターフェイス実装を追加する必要があります。例えば

:すなわち、直接返すPost代わりIData<Post>

public Post Select(int id) 
{ 
    MyDataContext dc = MyDataContext.Create(); 
    return dc.Posts.Single(p => p.PostID == id); 
} 

を試みるについて

public partial class Post : IData<Post> { 
    Post Select(int id) { ... } 
    IData<Post> IData<Post>.Select(int id) { return Select(id); } 
} 
+0

これはうまくいきますが、Interfaceを満たす方法と実際の使用方法を作成するのは奇妙に思えます。 – Lazlow

+3

@Lazlow、あなたが思うより頻繁に行われます。たとえば、 'IEnumerable 'を実装する場合は非常に一般的です。 'IEnumerable GetEnumerator()'は単に 'IEnumerable GetEnumerator()'を呼び出します。 – strager

1

何。

public interface IData<T> 
{ 
    T Select(int id); 
    List<T> SelectMultiple(); 
    void Insert(); 
    void Update(); 
    void Delete(); 
} 

をして実装します。

+0

その後、インターフェイスは実装されません。 – strager

+0

もちろん、リファクタリングする必要もあります。実際、上記のSLakの答えは同じ考えですが、適切に開発されています。 – Jon

+0

これは私が始めたところですが、シグネチャがInterfaceのシグネチャと一致しないためコンパイルされません。 – Lazlow

1

IData<Post>.Selectを明示的に実装し、適切な戻り値を持つSelectを提供する必要があります。あなたがこれを行う場合

IData<Post> IData<Post>.Select(int id) 
{ 
    return Select(id); 
} 

Post Select(int id) 
{ 
    MyDataContext dc = MyDataContext.Create(); 
    return dc.Posts.Single(p => p.PostID == id); 
} 

しかし、:たとえば

IData<Post> post = new Post(); 
Post p = post.Select(1); 

post.Select(1)まだIData<Post>を返します。これを可能にするには、インタフェースのリファクタリングでFemaref's answerを参照してください。

関連する問題