2011-01-19 6 views
5

私はそれを実装するインターフェイスと2つのクラスを持っています。私はコンパイラのエラーを取得しています、そして、私はなぜそれほど確かではありません。プロパティとしてのインターフェイス

interface IPerson 
{ 
    ICollection<string> NickNames{get;set;} 
} 
class ObservablePerson : IPerson 
{ 
    ObservableCollection<string> NickNames{get;set;} 
} 
class ListPerson : IPerson 
{ 
    List<string> NickNames{get;set;} 
} 

私は、これはリストとのObservableCollectionとして、仕事の両方いるICollectionを実装しない理由を理解トラブルのビットを持っています。

+0

コンパイラのエラーを明記してください。 –

+0

@ Robert、ObservablePersonはインターフェースメンバーIPerson.NickNamesを実装していないでしょう。そして、その点では、実装も公開しなければなりません。 –

+0

これは何百もの分散問題の複製です。 –

答えて

6

私は、これはリストとのObservableCollectionとして、仕事の両方いるICollectionを実装しない理由を理解トラブルのビットを持っています。

はい、インターフェイスにはICollection<string>が返されます。基になるタイプはObservableCollection<string>またはList<string>ですが、シグネチャはインターフェイスに準拠する必要があります。 ObservableCollection<string>ICollection<string>ですが、ICollection<string>は必ずしもObservableCollection<string>である必要はありません。

また、メソッドは公開されている必要があります(現在は非公開です)。インターフェイスはプライベートメソッドまたはプロテクトメソッドを処理しません。publicインターフェイスを定義します。

+0

詳細については、プロパティにセッターがあることを確認してください。'IPerson'の消費者は、プロパティを* ICollection に設定できると思うべきですが、提供されたコードが実際にコンパイルできるかどうかは明らかです。 –

+0

はい、良い点。 –

+0

ええ、パブリック修飾子を追加するのを忘れました。 – user582181

0

あなたの問題は、両方のサブクラスがICollectionの型を返すと予想されることです。 Getアクセサを使用してListまたはObservableCollectionを返すことはできますが、宣言されたメンバータイプはICollectionのままにする必要があります。

1

それは

interface IPerson 
{ 
    ICollection<string> NickNames{get;set;} 
} 
class ObservablePerson : IPerson 
{ 
    ICollection<string> NickNames{get;set;} 
} 
class ListPerson : IPerson 
{ 
    ICollection<string> NickNames{get;set;} 
} 

する必要があり、実装の内部では、ListオブジェクトまたはのObservableCollection

編集コード

interface IPerson 
    { 
     ICollection<string> NickNames{get;set;} 
    } 

public class ObservablePerson : IPerson 
    { 
     ICollection<string> nickNames = new ObservableCollection<string>(); 

     public ICollection<string> IPerson.NickNames 
     { 
      get 
      { 
       return nickNames; 
      } 
      set 
      { 
       nickNames = value; 
      } 
     } 
    } 
    public class ListPerson : IPerson 
    { 
     ICollection<string> nickNames = new List<string>(); 

     public ICollection<string> IPerson.NickNames 
     { 
      get 
      { 
       return nickNames; 
      } 
      set 
      { 
       nickNames = value; 
      } 
     } 
    } 
+0

ObservablePersonクラスを使用する人は、NickNamesをObservableCollectionにキャストするだけでよいでしょうか?それとも良い方法がありますか? – user582181

+0

キャストの必要がないようにコードを更新しました。 – Divi

0
コンパイラは正確な型の一致を主張します

を返すことができますが、インターフェイスではなくクラス上でアクセスしたときにプロパティをシャドーできます。ただし、インターフェイスを介して設定する場合、別の種類のICollection<string>を割り当てる可能性があります。そのため、例外が発生します。

interface IPerson 
{ 
    ICollection<string> NickNames { get; set; } 
} 
class ObservablePerson : IPerson 
{ 
    public new ObservableCollection<string> NickNames { get; set; } 
    ICollection<string> IPerson.NickNames 
    { 
     get { return NickNames; } 
     set { NickNames = (ObservableCollection<string>)value; } 
    } 
} 
class ListPerson : IPerson 
{ 
    public new List<string> NickNames { get; set; } 
    ICollection<string> IPerson.NickNames 
    { 
     get { return NickNames; } 
     set { NickNames = (List<string>)value; } 
    } 
} 
0

私はちょうど同様の問題に遭遇しました。私の友人は優れたソリューションを提案しました:一般的なタイプ。ここで何ができるかです:ここでは

public interface IPerson<CollectionType> where CollectionType : ICollection<string> 
{ 
    CollectionType NickNames { get; set; } 
} 

class ObservablePerson : IPerson<ObservableCollection<string>> 
{ 
    public ObservableCollection<string> NickNames { get; set; } 
} 

public class ListPerson : IPerson<List<string>> 
{ 
    public List<string> NickNames { get; set; } 
} 

、「CollectionTypeはは」一般的であり、あなたはそれは多くの場合、.NET Frameworkの全体Tと呼ばれています(好きな名前を付けることができますが、それを私が感じる意味のある名前を与えることは有用です)。これにより、ObservablePersonとListPersonにインターフェイスを実装することができます。ただし、それぞれにNickNamesプロパティの異なる型があります(ただし、CollectionTypeで使用する任意の型はICollectionを実装する必要があります)。

関連する問題