2010-11-17 16 views
1

Je me sentais assez malin quand j'ai travaillé sur la création de sous-classes en C# pour un projet ASP.NET, puis j'ai trouvé un problème - je ne savais pas comment créer un objet de la sous-classe droite en fonction des résultats d'une requête SQL.Comment créer la bonne sous-classe basée sur la valeur dans la ligne SQL

Dites que vous avez une classe appelée Animal et deux sous-classes appelées Zebra et Elephant. Vous avez eu l'idée? Ce que je veux faire est d'effectuer une requête SQL et si la ligne retournée a une ligne ["Type"] = "Zebra" alors charger un objet Zebra (ou si c'est un éléphant alors ..).

Ainsi, en principe, la classe d'animaux aurait une méthode statique:

class Animal{ 
public static Animal Load(DataRow row){ 
    if (row["Type"]=="Zebra"){ 
    return new Zebra(); 
    } 
} 

class Zebra : Animal{ 
//some code here 
} 

Est-ce la mesure du possible ou ai-je tout simplement eu l'idée de sous-classes mal. Il devrait être évident que je ne suis pas un expert OO.

Merci à l'avance, Jake

Répondre

5

Vous pouvez mettre en œuvre le modèle d'usine de méthode. http://en.wikipedia.org/wiki/Factory_method_pattern

+0

+1: Le modèle d'usine est probablement la meilleure solution ici à court d'avoir le code savoir à l'avance quel type d'animal il récupère. – NotMe

+0

Toujours demandé ce que les usines ont fait ;-) Sons prometteurs. Désolée de regarder maintenant. –

+0

On dirait exactement ce dont j'avais besoin. Merci! –

0

Je pense qu'il est bien:

public class Animal 
{ 
    public static Animal Load(string row) 
    { 
     if (row == "Zebra") 
     { 
      return new Zebra(); 
     } 
     else if (row == "Elephant") 
     { 
      return new Elephant(); 
     } 

     return null; 
    } 
} 

public class Zebra : Animal 
{ 
    public new string ToString() 
    { 
     return "Zebra"; 
    } 
} 

public class Elephant : Animal 
{ 
    public new string ToString() 
    { 
     return "Elephant"; 
    } 
} 

static void Main(string[] args) 
{ 
    Animal a1 = Animal.Load("Zebra"); 
    System.Console.WriteLine(((Zebra)a1).ToString()); 

    System.Console.WriteLine(((Elephant)a1).ToString()); // Exception 

    Animal a2 = Animal.Load("Elephant"); 
    System.Console.WriteLine(a2.ToString()); 
} 
+0

Etes-vous sûr que cela fonctionne? C'est ce que j'avais essayé et il n'en avait aucune - se plaignait de ne pas être capable de jeter un animal à un zèbre (IRIC) –

+0

Ça marche bien. Pour simplifier, j'ai changé la ligne de paramètre en type de chaîne. –

1

Essayez ceci:

public interface IAnimal 
{ } 

public class Animal : IAnimal 
{ 
    public static IAnimal Load(String type) 
    { 
     IAnimal animal = null; 
     switch (type) 
     { 
      case "Zebra" : 
       animal = new Zebra(); 
       break; 
      case "Elephant" : 
       animal = new Elephant(); 
       break; 
      default: 
       throw new Exception(); 

     } 

     return animal; 
    } 
} 

public class Zebra : Animal 
{ 
    public int NrOfStripes { get; set; } 

    public static Zebra ZebraFactory() 
    { 
     return new Zebra(); 
    } 
} 

public class Elephant : Animal 
{ 
    public int LengthOfTrunk { get; set; } 
} 

Et pour essayer:

class Program 
{ 
    static void Main(string[] args) 
    { 
     IAnimal zebra = Animal.Load("Zebra"); 
     IAnimal elephant = Animal.Load("Elephant"); 
    } 
} 
+0

ce n'est pas vraiment une sous-classe cependant - Zebra n'est pas une sous-classe de Animal, il implémente juste l'interface. Même si je pense que cela fonctionnerait pour le PO, je ne pense pas que cela répond vraiment à la question. –

+0

Merci d'avoir signalé cela. Je classe mal les zèbres et les éléphants qui devraient bien sûr hériter des animaux. Mise à jour ma réponse – Jocke

+0

Hmm, je suis confus maintenant. –