我有两个这样的界面:
public interface IMyInterface1
{
string prop1 { get; set; }
string prop2 { get; set; }
}
public interface IMyInterface2
{
string prop1 { get; set; }
IList<IMyInterface1> prop2 { get; set; }
}
我已经定义了两个实现接口的类:
public class MyClass1 : IMyInterface1
{
public string prop1 {get; set;}
public string prop2 {get; set;}
}
public class MyClass2 : IMyInterface2
{
public string prop1 {get; set;}
public IList<MyClass1> prop2 {get; set;}
}
但是当我构建代码时,我有以下错误消息:
'ClassLibrary1.MyClass2'没有实现接口成员'ClassLibrary1.IMyInterface2.prop2'。 'ClassLibrary1.MyClass2.prop2'无法实现'ClassLibrary1.IMyInterface2.prop2',因为它没有匹配的返回类型'System.Collections.Generic.IList'
如何在我班上实现IMyInterface2的“IList prop2”?
答案 0 :(得分:7)
您的界面要求实现类提供IList<IMyInterface1>
类型的属性,而不是IList<class that implements IMyInterface1>
。
如果您希望这项工作正常,则需要IMyInterface2
通用:
public interface IMyInterface2<T> where T : IMyInterface1
{
string prop1 { get; set; }
IList<T> prop2 { get; set; }
}
然后MyClass2
成为:
public class MyClass2 : IMyInterface2<MyClass1>
{
public string prop1 {get; set;}
public IList<MyClass1> prop2 {get; set;}
}
答案 1 :(得分:1)
这是因为您的接口MyInterface2
有一个属性,它是类型IInterface1
的通用列表,并且在实现此接口的类中,即MyClass2
您已将该属性声明为类型列表MyClass1
。
要修复此问题,请将Prop2
的类定义更改为MyInterface1
列表,或将Prop2
的接口定义更改为MyClass1
列表。< / p>
e.g。
public interface MyInterface2
{
public IList<MyInterface1> Prop2 { get; set; }
}
public class MyClass2 : MyInterface2
{
public IList<MyInterface1> Prop2 { get; set; }
}
答案 2 :(得分:1)
我不确定我是否将此称为the question from yesterday的副本,但是......
.NET不支持返回类型协方差。这意味着您无法从实现需要更通用类型的接口的类返回派生类型。
解决方法是显式实现界面成员,给您带来麻烦:
public class MyClass2 : IMyInterface2
{
public string prop1 { get; set; }
public IList<MyClass1> prop2 { get; set; }
public IList<IMyInterface1> IMyInterface2.prop2
{
get { return prop2.Cast<IMyInterface1>.ToList(); }
set { prop2 = value.Cast<MyClass1>().ToList(); }
}
}
在这种情况下,如果您尝试调用IMyInterface.prop2.Add()
,那么显式实现这样的界面会导致问题,因为IMyInterface.prop2
不再引用与prop2相同的集合。
解决问题的另一种方法是实现Adam的建议并使IMyInterface2
通用,这样您就可以提供任何实现IMyInterface1
的类型。
答案 3 :(得分:0)
MyClass2
必须实现在接口中声明的属性:
public class MyClass2 : IMyInterface2
{
public string prop1 {get; set;}
public IList<IMyInterface1> prop2 {get; set;}
}
即使MyClass1
实施IMyInterface1
,也可能会导致以下情况出现问题:
IMyInterface2 myInterface2 = new MyClass2();
myInterface2.prop2.Add(new OtherImplementationOfIMyInterface1());
任何使用该类的人都希望能够分配任何实现IMyInterface1
的实例,但该类需要MyClass1
的具体实例。
答案 4 :(得分:0)
试图像这样实现代码的问题是这样的。如果编译器允许您编译该代码,那么您可以编写如下代码:
public class MyClass3 : IMyInterface1
{
public string prop1 {get; set;}
public string prop2 {get; set;}
}
...
MyClass2 mc2 = new MyClass2();
IMyInterface2 mi2 = mc2;
mi2.prop2 = new List<MyClass3>();
接口应该允许你放置任何IList&lt; IMyInterface2&gt;进入prop2,但MyClass2无法处理。这就是为什么你不能像你建议的那样实现可写属性的原因。