2011-12-22 14 views
1

Collectionプロパティを持つタイプ(以下の例ではMyType)を実装しています。内にはMyType私は実際にどのようなコレクションの種類が気にしません。私が気にしているのは、それがIEnumerable<String>INotifyCollectionChangedです。これらの制限を使用してCollectionプロパティを実装するにはどうすればよいですか?ここでは、インターフェイスの継承が適切なのでしょうか。なぜ機能しませんか?

を私は新しいインターフェース作成:

interface INotifyEnumerableCollectionChanged<T> : IEnumerable<T>, INotifyCollectionChanged {} 

をし、タイプINotifyEnumerableCollectionChanged<String>MyTypeCollection財産を作ったここ

は、私が試したものです。これはMyTypeの内部で動作するようです。私はそのコレクションを列挙してCollectionChangedイベントを登録できるようです。

しかし、私はさえ厳しいMyCollectionIEnumerable<String>INotifyCollectionChangedの両方を実装し、コレクション(以下の例ではMyCollection)にこのプロパティを設定することはできません。

コンパイラは言う:

が暗黙的にタイプ 'InterfaceInheranceTest.Program.MyCollection' は に変換できません 'InterfaceInheranceTest.Program.INotifyEnumerableCollectionChanged'。 明示的な変換が存在する(あなたが キャストが欠けている?)

これを行うには正しい方法は何ですか?ここで

は、完全なサンプルコードです:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.Specialized; 

namespace InterfaceInheranceTest 
{ 
    class Program 
    { 

     interface INotifyEnumerableCollectionChanged<T> : IEnumerable<T>, INotifyCollectionChanged {} 

     class MyCollection : IEnumerable<String>, INotifyCollectionChanged 
     { 

      IEnumerator<String> IEnumerable<String>.GetEnumerator() 
      { throw new NotImplementedException(); } 

      System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
      { throw new NotImplementedException(); } 

      public event NotifyCollectionChangedEventHandler CollectionChanged; 
     } 

     class MyType 
     { 
      private INotifyEnumerableCollectionChanged<String> _Collection; 

      public INotifyEnumerableCollectionChanged<String> Collection 
      { 
       get { return _Collection; } 
       set 
       { 
        _Collection = value; 
        _Collection.CollectionChanged += new NotifyCollectionChangedEventHandler(_Collection_CollectionChanged); 
        foreach (var item in _Collection) 
        { 
         Console.WriteLine(item); 
        } 
       } 
      } 

      void _Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
      { throw new NotImplementedException(); } 
     } 


     static void Main(string[] args) 
     { 
      var collection = new MyCollection(); 
      var type = new MyType(); 
      type.Collection = collection; // compiler doesn't like this! 
     } 
    } 
} 

答えて

3

あなたのクラスがINotifyEnumerableCollectionChanged<T>を実装する必要があります。

class MyCollection : INotifyEnumerableCollectionChanged<string>. 
         IEnumerable<string>, INotifyCollectionChanged 
    { 

     IEnumerator<String> IEnumerable<String>.GetEnumerator() 
     { throw new NotImplementedException(); } 

     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     { throw new NotImplementedException(); } 

     public event NotifyCollectionChangedEventHandler CollectionChanged; 
    } 

使用する変数(_collectionが)タイプINotifyEnumerableCollectionChanged<T>であるため、これが必要とされています。ただし、クラスMyCollectionChangedはこのインターフェイスを実装していないため、変数への参照として割り当てることはできません。

+0

コンパイル済みです。しかし、なぜこれが必要ですか?すでに 'IEnumerable 'と 'INotifyCollectionChanged'を実装しています。そして、 'INotifyEnumerableCollectionChanged 'は実際に何も追加しません。 –

+0

@RobertHegner - 使用する変数のタイプを 'INotifyEnumerableCollectionChanged 'と定義しています。実装はこのインタフェースを実装していないため、このインタフェースを有効な参照として使用することはできません。 – Oded

+0

あなたのソリューションと説明に感謝します!私は4分で受け入れるだろう... :) –

1

新しいインターフェイスを作成しましたが、使用していません。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.Specialized; 

namespace InterfaceInheranceTest 
{ 
    class Program 
    { 

     interface INotifyEnumerableCollectionChanged<T> : IEnumerable<T>, INotifyCollectionChanged {} 

     class MyCollection : INotifyEnumerableCollectionChanged<String> // Use your interface 
     { 

      IEnumerator<String> IEnumerable<String>.GetEnumerator() 
      { throw new NotImplementedException(); } 

      System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
      { throw new NotImplementedException(); } 

      public event NotifyCollectionChangedEventHandler CollectionChanged; 
     } 

     class MyType 
     { 
      private INotifyEnumerableCollectionChanged<String> _Collection; 

      public INotifyEnumerableCollectionChanged<String> Collection 
      { 
       get { return _Collection; } 
       set 
       { 
        _Collection = value; 
        _Collection.CollectionChanged += new NotifyCollectionChangedEventHandler(_Collection_CollectionChanged); 
        foreach (var item in _Collection) 
        { 
         Console.WriteLine(item); 
        } 
       } 
      } 

      void _Collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
      { throw new NotImplementedException(); } 
     } 


     static void Main(string[] args) 
     { 
      var collection = new MyCollection(); 
      var type = new MyType(); 
      type.Collection = collection; // compiler doesn't like this! 
     } 
    } 
} 

同じメソッドを定義しても、同じ型ではありません。

関連する問題