实现与另一个接口属性的IList的接口的类...如何?

时间:2010-09-09 12:57:17

标签: c# class interface properties ilist

我有两个这样的界面:

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”?

5 个答案:

答案 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无法处理。这就是为什么你不能像你建议的那样实现可写属性的原因。