2009-03-24 7 views
9

J'ai la structure suivante:Spécification du type de retour d'une méthode abstraite d'une classe de base selon une sous classe

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

    } 
} 

Je veux créer une méthode abstraite qui retourne quelle que soit la classe de la classe concrète sous est. Ainsi, comme vous pouvez le voir dans l'exemple, la méthode dans SubOne doit renvoyer List<SubOne> tandis que la méthode dans SubTwo doit renvoyer List<SubTwo>.

Quel type dois-je spécifier dans la signature déclarée dans la classe de base?


[UPDATE]

Merci pour les réponses affichées.

La solution est de faire la classe abstraite générique, comme par exemple:

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

    } 
} 
+1

Dans votre mise à jour/réponse, comment voulez-vous créer une liste ou d'une collection de la classe « de base » qui peut contenir à la fois SubOne et SubTwo objets? –

Répondre

18

Votre classe abstraite doit être générique.

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

Si vous avez besoin de se référer à la classe abstraite sans l'argument de type générique, utilisez une interface:

interface IBase { 
     //common functions 
} 

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

Excellent, exactement ce que je cherchais. Merci –

+0

Dang, j'ai * appris * à taper plus vite. –

1

Je ne pense pas que vous pouvez l'obtenir pour être la sous-classe spécifique. Vous pouvez le faire si:

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

Essayez ceci:

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