Правильно ли здесь делать наследование интерфейса и почему оно не работает? - PullRequest
1 голос
/ 22 декабря 2011

Я реализую некоторый тип (MyType в примере ниже), который имеет свойство Collection.Внутри MyType Мне все равно, что это за коллекция.Единственное, что меня волнует, это то, что он реализует IEnumerable<String> и INotifyCollectionChanged.Как мне реализовать свойство Collection с этими ограничениями?

Вот что я попробовал:

Я создал новый интерфейс:

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

и сделалсвойство Collection в MyType типа INotifyEnumerableCollectionChanged<String>.Кажется, это работает внутри MyType.Похоже, я могу перечислить эту коллекцию и зарегистрировать событие CollectionChanged.

Но я не могу установить это свойство для коллекции (MyCollection в приведенном ниже примере), даже жесткие MyCollection реализациии IEnumerable<String> и INotifyCollectionChanged.

Компилятор говорит:

Невозможно неявно преобразовать тип 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!
        }
    }
}

Ответы [ 2 ]

3 голосов
/ 22 декабря 2011

Ваш класс должен реализовать 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 не реализует этот интерфейс, поэтому его нельзя назначить ссылкой на переменную.

1 голос
/ 22 декабря 2011

Вы создали новый интерфейс, но не используете его.

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!
        }
    }
}

Определение тех же методов не означает, что это тот же тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...