实现通用接口覆盖时的限制

时间:2018-03-26 16:45:14

标签: c# inheritance polymorphism

如果我有以下接口和类:

public interface IPopulationUnit<T>
{
    IPopulationUnit<T> Breed();
}

 public abstract class PopulationUnit<T>:IPopulationUnit<T>
{
    public abstract PopulationUnit<T> Breed();
}

然后我有一个实现

class StringUnit : PopulationUnit<string>
{        
    public override StringUnit Breed()
    {

    }
}

代码无法编译,因为Breed方法与类型IPopulationUnit<string>不匹配,但技术上并不是这样吗?我的意思是,StringUnit本身就是PopulationUnit<string>本身就是IPopulationUnit<string>所以我认为它会起作用。

如何将StringUnit Breed方法限制为返回类型StringUnit,但是遵守继承规则?

3 个答案:

答案 0 :(得分:1)

Oekelens离我们很近...如果您真的出于某种奇怪的原因想要这样做,请对其施加一些约束:

public interface IPopulationUnit<T, T1> where T1 : IPopulationUnit<T, T1>
{
    T1 Breed();
}

public abstract class PopulationUnit<T, T1> : IPopulationUnit<T, T1> where T1 : PopulationUnit<T, T1>
{
    public abstract T1 Breed();
}

public class StringUnit : PopulationUnit<string, StringUnit>
{        
    public override StringUnit Breed()
    {
        throw new NotImplementedException();
    }
}

为什么它不像您所拥有的那样起作用?因为您的类必须必须实现声明的接口;包括返回类型。您可以返回自己喜欢的任何内容-但必须在定义中引用它,方法与接口相同。

答案 1 :(得分:0)

这似乎有效,在您的界面和抽象实现中添加了一个T1:

    public interface IPopulationUnit<T, T1> where T1 : IPopulationUnit<T, T1>
    {
        T1 Breed();
    }

    public abstract class PopulationUnit<T> : IPopulationUnit<T, PopulationUnit<T>>
    {
        public abstract PopulationUnit<T> Breed();
    }

    class StringUnit : PopulationUnit<string>
    {
        public override PopulationUnit<string> Breed()
        {
            return new StringUnit();
        }
    }

如果我将覆盖定义为StringUnit Breed()(说它必须返回PopulationUnit<string>以覆盖Breed()),我仍然会收到错误,但您可以实际上从teh方法本身返回StringUnit

答案 2 :(得分:0)

定义中的返回类型必须与接口完全匹配。

但是你可以自由地返回任何实现该接口的东西:

public abstract class PopulationUnit<T>:IPopulationUnit<T>
{
    public abstract IPopulationUnit<T> Breed();
}

class StringUnit : PopulationUnit<string>
{        
    public override IPopulationUnit<string> Breed()
    {
        return new StringUnit(); 
    }
}