实现.Net接口(C#)

时间:2011-04-07 21:22:50

标签: c# .net interface

可能是一个简单的问题。

我有一个接口(MyInterface)定义了如下属性:

IList<IMenuItem> MenuCollection { get; }

实现MyInterface的类

public class MyClass : MyInterface
{
    public ObservableCollection<MenuItemBase> MenuCollection 
    {
       get
       {
           ...
       }
    }
    ....
}

从我读到的内容,ObservableCollection继承自一个IList的Collection,我有一个IMIuItem的MenuItemBase类 - 不会满足接口吗?

我认为接口必须明确实现?

我也试过这个:

public class MyClass : MyInterface
{
    public IList<IMenuItem> MenuCollection MenuCollection 
    {
       get
       {
           if(_menuCollection == null)
              _menuCollection = new ObservableCollection<MenuItemBase>();
           return _menuCollection as IList<IMenuItem>;
       }
    }
    private ObservableCollection<MenuItemBase> _menuCollection;
}

似乎是一个变通方法的黑客(我确实遇到了一些问题,说没有实例化MenuCollection)来让界面得到满足......是否有更好的方法来实现IInterface1<IInterface2>个对象? / p>

我之所以需要这种抽象,是因为我正在构建一个prism / unity应用程序,并希望尽可能地将菜单视图模型与显示菜单的功能区ui分离。

3 个答案:

答案 0 :(得分:7)

乔是正确的;这与通用差异无关。但是,他没有提到您想要的功能称为返回类型协方差

也就是说,如果Animal是Giraffe的基本类型,那么返回Animal的接口方法或返回Animal的虚拟方法可以通过返回Giraffe的方法来实现/专门化。由于每只长颈鹿都是动物,合同即可实现。

C#不支持返回类型协方差;就此而言,CLR也不是。有些语言支持返回类型协方差;例如,C ++就会浮现在脑海中。 (C ++ / CLI实现做了一些偷偷摸摸的技巧来解决CLR的限制。)实现的接口方法的返回类型,属性的类型等等都必须与完全匹配在C#中。

答案 1 :(得分:6)

这与通用差异无关

有多个答案在谈论泛型方差。这与示例无关。如果您尝试使用IList(无泛型)实现定义为ArrayList的属性,您将看到仍然无法执行此操作。

正确答案

这种行为是因为如果你可以将MenuCollection实现为实现IList<T>的某种类型的属性(或者从它派生,如果它没有被指定为接口),那么这将是可能的:

public interface MyInterface
{
    IList<IMenuItem> MenuCollection { get; set }
}

public class MyClass : MyInterface
{
    // WARNING: Does not count as implementing the interface -- with good reason
    public ObservableCollection<MenuItemBase> MenuCollection { get; set; }
}

var myClass = new MyClass();
var classAsInterface = (MyInterface) myClass; // This is OK of course

classAsInterface.MenuCollection = new List<MenuItemBase>(); // OOPS!!

在最后一行中,您已为List<MenuItemBase>分配了一个MyInterfaceMyInterface.MenuCollection可以告诉,因为IList<MenuItemBase>类型为ObservableCollection<MenuItemBase>)属于List<MenuItemBase>类型。

当然这不合法,因为ObservableCollection<MenuItemBase>显然不是来自{{1}}。但是,如果您能够实现这样的界面,那将是可能的。

答案 2 :(得分:0)

List<T>IList<T>不支持协方差

请参阅此问题:Question about C# covariance