2012-03-14 9 views
2

は、これは、Visual Studioで2010取得警告は、「タイプパラメータXを隠しインタフェースX」

私は一般的な方法で作業し、基本的に私のインテリセンスを失うと、このプロジェクトの作業を続けてから私を停止していますが発生しています。だから私はそれが動作するように期待される正確にどのような作品を削除

public abstract class DataRepository<T> 
{ 
    public virtual IEnumerable<T> RetrieveAll<U>(U parameter1) 
    { 
     throw new NotImplementedException(); 
    } 

    public virtual bool Delete<U>(U parameter1) 
    { 
     throw new NotImplementedException(); 
    } 
} 

:からこれが継承

public class SearchRepository : DataRepository<IAudit> 
{ 
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters) 
    { 
     // CODE GOES HERE 
    } 

    public override bool Delete<TIAudit>(IAudit audit) 
    { 
     // CODE GOES HERE 
    } 
} 

は、私は基本的に以下のクラスがあります。私は知性があり、それは正しくコンパイルされます。 RetrieveAllはIAuditSearchを使用して正しく動作しません。私がTIAuditSearchに変更した場合、私は「無効にする適切な方法はありません」と言います。

私が間違っていることがわかりませんが、間違いなく私には満足していません。

UPDATED:上のDeleteメソッドで上書きするように仮想を変更しました。それは間違いだった。

+0

'抽象型 'の内部に実装されていない' virtuals'は正しいのですか?私はあなたが代わりに '抽象'キーワードを使用するべきだと思います – Tigran

+0

その理由は、私はコードの一部を示したということです。要約には8-10のメソッドがあります。各リポジトリは、それらのうちのいくつかだけを上書きします。 – Cyfer13

+0

あなたの回答はあなたの質問に役立ちますか?そうであれば、それを受け入れるべきです。 – Andy

答えて

1

あなたは方法公共オーバーライドIEnumerableをRetrieveAll(IAuditSearch searchParameters)を定義することはできません

まだIAuditSearchの代わりにU型パラメータを使用する必要があります方法。どのタイプを選択するかは、呼び出し元までです。

おそらく、ISearchインターフェイスを作成する必要があります。ベースクラスでは、U:ISearchの場所を追加しますが、サブクラスでもIAuditSearchだけでなくすべてのISearch実装を受け入れる必要があります。

おそらく最も良い解決策は、あなたのRetreiveAllメソッドを定義するIAuditSearchリポジトリを定義することです。

編集:質問が変更されています。両方の方法で同じ問題が発生しました。メソッドをオーバーライドするときに使用するインタフェースを指定することはできません。ジェネリック型のパラメータを維持する必要があります。

public override IEnumerable<T> RetrieveAll<U>(U parameter1) { } 

public override bool Delete<U>(U parameter1) { } 

メソッドにwhere句を追加することはできません。これによりLiskov Substitution Prinicpleが破損します。また、私はコンパイラがあなたにそれをさせることを許可しているかどうかも分かりません。

5

あなたが暗黙のうちにあなたは私が派生クラスのDeleteプロパティに「新しい」キーワードを導入し、エラーを克服することができます(オーバーライドしないことによって)

bool Delete<myType>(myType param) { ... } 

のメソッドシグネチャを隠しています。これは明示的に署名を隠し、誰もがあなたの意図を示すように幸せにします。

http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspxのMicrosoftのドキュメントをお読みください。

+0

クラスの多型を破るので、それは私を幸せにしません。さて、オーバーライドされたクラスへの参照があれば、新しい方法で動作しますが、それを基底型にキャストすると、古いものと同じように動作します。一般的に言えば、私はメンバー隠蔽のための 'new'キーワードを嫌います。 –

+0

ポリモーフィズムを維持したい場合は、 "override"キーワードを使用するだけでよく、オブジェクトをキャストして基本メソッドにアクセスできます。隠れていることについては、私はパターンを知らないが、これは明示的に基底派生へのアクセスを削除すると信じている。どうして?私はsomeonesの例を聞いてみたい。 –

+0

私は仮想をミスタイプし、オーバーライドされるはずだった。上記のコードを更新しました。 – Cyfer13

0

残念ながら、正確なコンテキストは、私には非常に明確ではないですが、私はあなたのコードは次のようになりますと信じて:

異なるIAuditSearchの実装は、「異なるパラメータによる検索」の論理incapsulateます
public interface IParameter<T> { 
    bool Match(T entry); 
} 
public abstract class DataRepository<T, TParameter> 
    where TParameter : IParameter<T> { 
    public abstract IEnumerable<T> RetrieveAll(TParameter parameter1); 
    public abstract bool Delete(TParameter parameter1); 
} 
// 
public interface IAudit {/* ... */} 
public interface IAuditSearch : IParameter<IAudit> {/* ... */} 

public class SearchRepository : DataRepository<IAudit, IAuditSearch> { 
    public override bool Delete(IAuditSearch parameter1) { 
     // iterate by collection items using parameter matching 
     // CODE GOES HERE (DELETE ALL FOUND ENTRIES) 
    } 
    public override IEnumerable<IAudit> RetrieveAll(IAuditSearch parameter1) { 
     // iterate by collection items using parameter matching 
     // CODE GOES HERE (RETURN ALL FOUND ENTRIES) 
    } 
} 

var guidSearchResult = repository.RetrieveAll(
    new GuidSearch(new Guid("00000000-0000-0000-0000-000000000000"))); 
var idRangeSearchResult = repository.RetrieveAll(
    new IDRangeSearch(1000, 2000)); 
GuidSearchとIDRangeSearchは次のように実装されて

public class GuidSearch : IAuditSearch { 
    Guid ID; 
    public GuidSearch(Guid id) { 
     this.ID = id; 
    } 
    public bool Match(IAudit entry) { 
     /* search implementation using ID(Guid)*/ 
     throw new NotImplementedException(); 
    } 

} 
public class IDRangeSearch : IAuditSearch { 
    int StartID; 
    int EndID; 
    public IDRangeSearch(int startId, int endId) { 
     this.StartID = startId; 
     this.EndID = endId; 
    } 
    public bool Match(IAudit entry) { 
     /* search implementation using ID range (StartID...EndID)*/ 
     throw new NotImplementedException(); 
    } 
} 
+0

異なるメソッドに異なるパラメータを渡したいのですが? Guid型のパラメータを必要とする検索メソッドがある場合はどうなりますか? – Cyfer13

+0

@ Cyfer13:私のアイデアのより詳細な説明で私の答えを更新しました。このアプローチがあなたのニーズに合っているかどうかを確認してください。 – DmitryG

0

代わりに次のコードが動作しますか?

public class SearchRepository : DataRepository<IAudit, IAuditSearch> 
{ 
    public override IEnumerable<IAudit> RetrieveAll<IAuditSearch>(IAuditSearch searchParameters) 
    { 
     // CODE GOES HERE 
    } 

    public override bool Delete<TIAudit>(IAudit audit) 
    { 
     // CODE GOES HERE 
    } 
} 

public abstract class DataRepository<T, TSearch> 
{ 
    public virtual IEnumerable<T> RetrieveAll(TSearch parameter1) 
    { 
     throw new NotImplementedException(); 
    } 

    public virtual bool Delete(T parameter1) 
    { 
     throw new NotImplementedException(); 
    } 
} 

DataRepositoryをインスタンス化するたびに、結果の種類(T)と検索の種類(TSearch)を宣言します。

-c

+0

私がこれを見ている最大の問題は、検索パラメータを検証する必要があるということです。 RetrieveAll(guid x、guid y)の場合、両方の値を入力したことがわかります。検索オブジェクトの場合は、そのオブジェクトがnullでないことを保証することはできません。だから、あなたは何らかのiValidateが呼び出される必要があります。 – Cyfer13

関連する問題