Указание типа возврата абстрактного метода из базового класса в соответствии с подклассом - PullRequest
11 голосов
/ 24 марта 2009

У меня есть следующая структура:

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>.

Какой тип указывать в подписи, объявленной в базовом классе?


[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() {

    }
} 

Ответы [ 4 ]

25 голосов
/ 24 марта 2009

Ваш абстрактный класс должен быть универсальным.

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(); 
}
3 голосов
/ 24 марта 2009
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>(); }
}
1 голос
/ 24 марта 2009

Попробуйте это:

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.
}
1 голос
/ 24 марта 2009

Я не думаю, что вы можете сделать его конкретным подклассом. Вы можете сделать это, хотя:

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();
    }
}
...