根据子类从基类指定抽象方法的返回类型

时间:2009-03-24 01:26:41

标签: c# generics polymorphism abstract-class override

我有以下结构:

abstract class Base {
        public abstract List<...> Get(); //What should be the generic type?
}

class SubOne : Base {
    public override List<SubOne> Get() {

    }
}

class SubTwo : Base {
    public override List<SubTwo> Get() {

    }
}

我想创建一个抽象方法,返回具体子类的任何类。因此,正如您从示例中看到的那样,SubOne中的方法应返回List<SubOne>,而SubTwo中的方法应返回List<SubTwo>

我在Base类中声明的签名中指定了哪种类型?


[UPDATE]

感谢您发布的答案。

解决方案是使抽象类具有通用性,如:

abstract class Base<T> {
        public abstract List<T> Get();
}

class SubOne : Base<SubOne> {
    public override List<SubOne> Get() {

    }
}

class SubTwo : Base<SubTwo> {
    public override List<SubTwo> Get() {

    }
} 

5 个答案:

答案 0 :(得分:25)

你的抽象类应该是通用的。

abstract class Base<T> {
        public abstract List<T> Get(); 
}

class SubOne : Base<SubOne> {
    public override List<SubOne> Get() {

    }
}

class SubTwo : Base<SubTwo> {
    public override List<SubTwo> Get() {
    }
}

如果需要引用不带泛型类型参数的抽象类,请使用接口:

interface IBase {
        //common functions
}

abstract class Base<T> : IBase {
        public abstract List<T> Get(); 
}

答案 1 :(得分:3)

public abstract class Base<T> 
{       
    public abstract List<T> Get(); 
}

class SubOne : Base<SubOne> 
{
    public override List<SubOne> Get() { return new List<SubOne>(); }
}

class SubTwo : Base<SubTwo> 
{
    public override List<SubTwo> Get() { return new List<SubTwo>(); }
}

答案 2 :(得分:1)

我认为你不能把它当作特定的子类。你可以这样做:

abstract class Base<SubClass> {
        public abstract List<SubClass> Get(); 
}
class SubOne : Base<SubOne> {
    public override List<SubOne> Get() {
        throw new NotImplementedException();
    }
}
class SubTwo : Base<SubTwo> {
    public override List<SubTwo> Get() {
        throw new NotImplementedException();
    }
}

答案 3 :(得分:1)

试试这个:

public abstract class Base<T> {
  public abstract List<T> Foo();
}

public class Derived : Base<Derived> {   // Any derived class will now return a List of
  public List<Derived> Foo() { ... }     //   itself.
}

答案 4 :(得分:0)

如果您的基类由于各种原因不能通用,此方法可能很有用:

abstract class Base {
}
interface IHasGetter<T> {
  List<T> Get();
}
static class HasGetterHelper {
    public static List<T> Get<T>(this T v) where T: IHasGetter<T>  => v.Get();
}
class SubOne : Base, IHasGetter<SubOne> {
    public List<SubOne> Get() {
        throw new NotImplementedException();
    }
}
class SubTwo : Base, IHasGetter<SubTwo> {
    public List<SubTwo> Get() {
        throw new NotImplementedException();
    }
}

如果您无法向子类添加接口,并且仍然无法向基本类型添加泛型,则此方法可能很有用: (不幸的是你不能保护 GetImpl,因为辅助类不允许在基类中)

abstract class Base {
    public abstract List<T> GetImpl<T>() where T:Base;
}
static class HasGetterHelper {
    public static List<T> Get<T>(this T v) where T: Base => v.GetImpl<T>();
}
class SubOne : Base {
    public override List<T> GetImpl<T>() {
        throw new NotImplementedException();
    }
}
class SubTwo : Base {
    public override List<T> GetImpl<T>() {
        throw new NotImplementedException();
    }
}

在这两种情况下,这都会按预期工作:

class Tester
{
   List<SubOne> TestIt() => new SubOne().Get();
}