C#用具体属性覆盖抽象属性

时间:2017-08-25 22:24:52

标签: c#

所以我有这个抽象类。其中有一个抽象类型列表

public abstract class BaseClass
{

    public abstract List<A> History { get; set; }

和继承者类。

public class ConcreteClass : BaseClass
{
    public override List<B> History { get; set; }

我的问题很简单。为什么会返回错误。 A是b继承的抽象类。那么为什么我的具体属性不能覆盖抽象属性呢?

注意:由于其他问题,我不能在基类中使用泛型。这个问题有些明确。我正在使用mvc并且由于动态类型的一些问题,我不能说BaseClass<t>而在其他一些方面,调用名为GetHistory()的方法的方法需要它返回具体列表而不是抽象列表。所以我被困在一块岩石和一块坚硬的地方之间。

2 个答案:

答案 0 :(得分:5)

  

为什么会返回错误。 A是B继承的抽象类。

再一次。每天都会问这个问题。

abstract class Fruit 
{
  public virtual List<Fruit> M() { return new List<Fruit>(); }
}
class Apple : Fruit
{
  public override List<Apple> M() { return new List<Apple>(); }
}

假设这是合法的。出了什么问题?

class Banana : Fruit { }

...

Fruit f = new Apple(); // Legal
List<Fruit> bowl = f.M(); // calls Apple.M, returns a list of apples.
bowl.Add(new Banana());

现在碗里有一个香蕉,可能只含有苹果。

这就是为什么这必须是非法的。搜索协方差和逆变以了解何时此类转换在C#中是合法的以及何时是非法的。简而言之,只有当编译器证明它是安全的,并且类型参数是引用类型时才合法。

现在,这个怎么样?

abstract class Fruit 
{
  public virtual Fruit N() { return new Banana(); }
}
class Apple : Fruit {
  public override Apple N() { return new Apple(); }
}
...
Fruit f1 = new Apple();
Fruit f2 = f1.N(); // No problem, an apple is a fruit.

这不会破坏类型系统;这将是安全的,但它仍然是非法的。这是非法的,因为虚拟返回类型协方差从未在C#中实现过。它是用C ++实现的。

它尚未实现,因为它从来都不是C#团队的高优先级。人们已经要求它超过十年,但这不是一个很好的功能。也许最终会完成;如果您对此感到强烈,请加入github上的论坛并提倡它。

答案 1 :(得分:0)

您可以考虑的一种方法是:

return response.json().then(data => { throw data });

通过使具体类指定它想要使用的确切泛型类型(re:基本类型),它可能适合您的目的。