Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实现.Net接口(C#)_C#_.net_Interface - Fatal编程技术网

实现.Net接口(C#)

实现.Net接口(C#),c#,.net,interface,C#,.net,Interface,可能是个简单的问题 我有一个接口(MyInterface),它定义了如下属性: IList<IMenuItem> MenuCollection { get; } IList菜单集合{get;} 以及实现MyInterface的类 public class MyClass : MyInterface { public ObservableCollection<MenuItemBase> MenuCollection { get

可能是个简单的问题

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

IList<IMenuItem> MenuCollection { get; }
IList菜单集合{get;}
以及实现MyInterface的类

public class MyClass : MyInterface
{
    public ObservableCollection<MenuItemBase> MenuCollection 
    {
       get
       {
           ...
       }
    }
    ....
}
公共类MyClass:MyInterface
{
公共可见集合菜单集合
{
得到
{
...
}
}
....
}
据我所知,ObservableCollection继承自一个IList集合,我有一个MenuItem类,它包含IMenuItem,这难道不能满足接口要求吗

我想接口必须显式实现

我也试过:

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;
}
公共类MyClass:MyInterface
{
公共IList MenuCollection MenuCollection
{
得到
{
if(_menuCollection==null)
_menuCollection=新的ObservableCollection();
返回作为IList的menuCollection;
}
}
私人可观察收集(menu collection);;
}
似乎是一种解决方法(我确实遇到了一些问题,说MenuCollection没有实例化),以使接口得到满足。。。。是否有更好的方法实现
IInterface1
对象

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

这与通用差异无关 关于一般差异,有多种答案。这与示例无关。如果尝试使用
ArrayList
(无泛型)实现定义为
IList
的属性,您会发现仍然无法实现

正确答案 此行为是因为,如果您可以将
MenuCollection
实现为某种类型的属性,实现
IList
(或者从中派生,如果未将其指定为接口),那么这将是可能的:

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!!
公共接口MyInterface
{
IList菜单集合{get;set}
}
公共类MyClass:MyInterface
{
//警告:不算作实现接口——有充分的理由
公共ObservableCollection菜单集合{get;set;}
}
var myClass=新的myClass();
var classAsInterface=(MyInterface)myClass;//这当然可以
classAsInterface.MenuCollection=新列表();//哎呀!!
在最后一行中,您已将
列表
(就
MyInterface
而言,这是正常的,因为
MyInterface.MenuCollection
属于
IList
)类型的属性分配给
ObservableCollection

当然,这样做是不合法的,因为
列表
显然不是从
可观测集合
派生出来的。但是,如果您可以实现这样的接口,这将是一种可能性。

List
IList
不支持协方差


看这个问题:

乔恩是正确的;这与一般方差无关。但是,他没有提到您想要的特性被称为返回类型协方差

也就是说,如果Animal是Giraffe的基本类型,那么返回Animal的接口方法或返回Animal的虚拟方法可以由返回Giraffe的方法实现/专门化。因为每只长颈鹿都是一种动物,所以合同就履行了


C#不支持返回类型协方差;在这方面,CLR也没有。一些语言支持返回类型协方差;例如C++。(C++/CLI实现使用了一些巧妙的技巧来绕过CLR的限制。)实现的接口方法的返回类型、属性的类型等等,都必须在C#中完全匹配

对我来说,你的“变通黑客”感觉是正确的方法……你甚至需要将
\u menuCollection
转换为
IList
?如果
observateCollection
满足
IList
,您应该能够直接返回它。。。你不应该吗?此外,我同意@Stormenet的说法,这不是真正的“黑客”。您已声明一个方法具有泛型返回类型,因此其实现需要泛型返回类型。这意味着方法的调用方不需要担心方法实现使用的具体内部类型。看起来不错。顺便说一句,你的
as
将始终返回null…@djacobson-我尝试直接返回它,但它导致编译时错误,我唯一的猜测是,它不喜欢为IList返回一个ObservableCollection——当我重新开始工作时,我将不得不再次检查确切的错误。您提到的这些技巧C++/CLI可能会引起有趣的阅读;)@乔恩:他们没那么狡猾。正是你所期待的。生成了一组助手方法,这些方法只是实际重载的代理。-1他在接口的
MenuCollection
属性中没有定义setter,只是一个getter。@Stormenet:显然,但是语言规则不能根据您是否定义setter而改变。