接口设计实现错误:...无法实现...因为它没有匹配的返回类型

时间:2013-12-17 02:01:27

标签: c# class interface

我在Library1中有几个类:上面的类使用的类A,类B等。

public class A 
{  
    int VarA1;  
}

public class B
{  
    List<A> SetA {get; set; }
    void MethodB1()
    {
            ...
            this.SetA = new List<A>;
            ...
    }
}

现在我想拥有该Library1的接口,因此可以有其他实现。调用接口库ILibrary:

public interface IA
{  
    int VarA1 {get; set; }  
}

public interface IB
{  
    List<IA> SetA { get; set; }
    void MethodB1();
}

正在Library1中实现:

public class A : IA
{  
    int VarA1{ get; set; }  
}

public class B : IB
{  
    List<IA> SetA {get; set; }
    void MethodB1()
    {
            ...
            this.SetA = new List<A>;
            ...
    }
}

但是我在这段代码中遇到了编译错误:

  

Library1.B.SetA无法实现ILibrary.IB.SetA,因为它没有匹配的返回类型。

我也尝试过:

public class B : IB
{  
    List<A> SetA {get; set; }
    void MethodB1()
    {
            ...
            this.SetA = new List<A>;
            ...
    }
}

但是这没有解决问题(相同的错误消息)。为什么会出现此错误,我该如何解决?

4 个答案:

答案 0 :(得分:3)

正如错误消息所示,为了符合界面,B.MethodB1必须返回IA类型,如下所示:

public class B : IB
{  
    public IA MethodB1() { ... }  
}

另一种方法是将IB声明为通用接口,如下所示:

public interface IB<out T> where T : IA
{  
    public T MethodB1();  
}

然后B像这样:

public class B : IB<A>
{  
    public A MethodB1() { ... }  
}

关于您更新的问题,您的问题仍然相同,解决方案也是如此。要么做这样的事情:

public class B : IB
{  
    public List<IA> SetA {get; set; }
    public void MethodB1()
    {
            ...
            this.SetA = new List<IA>();
            ...
    }
}

或者像这样:

public interface IB<T> where T : IA
{  
    List<T> SetA { get; set; }
    void MethodB1();
}

public class B : IB<A>
{  
    public List<A> SetA {get; set; }
    public void MethodB1()
    {
            ...
            this.SetA = new List<A>();
            ...
    }
}

答案 1 :(得分:1)

从接口实现方法必须返回完全相同的类型,并且IA与A不同。它们必须完全匹配,因此它必须返回IA。但是,您对MethodB1的B实现没有正文,并且该类不是抽象的,因此您仍然会收到错误。

答案 2 :(得分:1)

List<A>不会继承或实施List<IA>

接口IB需要List<IA>属性。 B类具有List<A>属性。

考虑:

interface IAnimal()
{
  public void HaveLunch();
}

class Zebra:IAnimal
class Lion:IAnimal


interface IZoo
{
  List<IAnimal> Zebras {get;set;}
  List<IAnimal> Lions {get;set;}
}

public class Zoo
  : IZoo //does not work
{
  List<Zebra> Zebras {get;set;}
  List<Lion> Lions {get;set;}
}


//...
IZoo myZoo = new Zoo;
myZoo.Zebras.Add(new Lion());  //because of this.

答案 3 :(得分:0)

其他答案已经说为什么这不起作用:

  • 继承的属性必须使用与父
  • 完全相同的类型
  • 您无法指定List<IA> myList = new List<A>();
    你必须使用相同的类型。这是因为List不是协变的。

因此,您必须在整个代码中使用IA而不是A,并且只使用IA可访问的公共方法

如果您将ASet的类型更改为IEnumerable<IA>,则有一种方法可以使其工作,同时仍然可以访问A:

  • 您可以指定IEnumerable<IA> myList = new List<A>();
    因为IEnumerable supports covariance,因为C#4.0

IEnumerable不支持List所做的所有方法,例如,您无法向IEnumerable添加更多元素。遗憾的是,这是使协方差工作所必需的。但是,您可以在内部使用B类中的List,并仅将IEnumerable呈现给外部。

public interface IB
{  
    IEnumerable<IA> SetA { get; set; }
    void MethodB1();
}

public class B : IB
{  
    private List<A> listA;

    public IEnumerable<IA> SetA 
    {
        get {return listA;} 
        set {throw new NotImplementedException();} 
        // the setter is somewhat inelegant, 
        // if you do not need the setter 
        // you should probably leave it out of the interface entirely
    }

    public void MethodB1()
    {
            this.listA = new List<A>()
    }
}