简体   繁体   English

接口继承是否在这里做正确的事情,为什么它不起作用?

[英]Is interface inheritance the right thing to do here, and why does it not work?

I'm implementing some type ( MyType in the example below) which has a Collection property. 我正在实现一些具有Collection属性的类型(下例中的MyType )。 Inside MyType I don't really care what kind of collection this is. MyType我真的不关心这是什么类型的集合。 The only thing I care is that it implements IEnumerable<String> and INotifyCollectionChanged . 我唯一关心的是它实现了IEnumerable<String>INotifyCollectionChanged How would I implement the Collection property with these restrictions? 如何使用这些限制实现Collection属性?

Here is what I've tried: 这是我尝试过的:

I created a new interface: 我创建了一个新界面:

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

and made the Collection property in MyType of type INotifyEnumerableCollectionChanged<String> . 并在MyType中使用类型为INotifyEnumerableCollectionChanged<String>Collection属性。 This seems to work inside MyType . 这似乎适用于MyType It looks like i can enumerate over that collection and register the CollectionChanged event. 看起来我可以枚举该集合并注册CollectionChanged事件。

But I can't set this property to a collection ( MyCollection in the example below), even tough MyCollection implements both IEnumerable<String> and INotifyCollectionChanged . 但我可以将此属性设置为一个集合( MyCollection在下面的例子中),甚至强硬MyCollection同时实现IEnumerable<String>INotifyCollectionChanged

The compiler says: 编译器说:

Cannot implicitly convert type 'InterfaceInheranceTest.Program.MyCollection' to 'InterfaceInheranceTest.Program.INotifyEnumerableCollectionChanged'. 无法将类型'InterfaceInheranceTest.Program.MyCollection'隐式转换为'InterfaceInheranceTest.Program.INotifyEnumerableCollectionChanged'。 An explicit conversion exists (are you missing a cast?) 存在显式转换(您是否错过了演员?)

What is the right way to do this? 这样做的正确方法是什么?

Here is the full example code: 这是完整的示例代码:

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

Your class needs to implement INotifyEnumerableCollectionChanged<T> . 您的类需要实现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;
    }

This is needed because the variable you use( _collection ) is of type INotifyEnumerableCollectionChanged<T> . 这是必需的,因为您使用的变量( _collection )的类型为INotifyEnumerableCollectionChanged<T> However, your class - MyCollectionChanged does not implement this interface, so can't be assigned as a reference to the variable. 但是,您的类 - MyCollectionChanged未实现此接口,因此无法将其指定为对变量的引用。

You created a new interface but you don't use it. 您创建了一个新界面但不使用它。

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

Defining same methods do not mean it's the same type. 定义相同的方法并不意味着它是相同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM