[英]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.