2017-05-01 1 views
-1

j'ai une classe de base appelée la tâche qui ressemble à ceci:Fonction mise en œuvre

public class Task{ 
    List<Task> subTasks = new List<Task>(); 
    public T executeTask<T>(){ 
     foreach(Task tsk in subTasks){ 
      tsk.executeTask(); 
     } 
    } 
} 

Et puis j'ai plusieurs autres tâches qui héritent de la classe des tâches comme Taska, TaskB et ainsi de suite. Ils devraient tous avoir leur propre implémentation de executeTask. Le problème auquel je fais face est que certaines Tâches effectuent des calculs et que certaines effectuent des opérations de chaîne par exemple et renvoient le résultat de l'opération, ce qui signifie que le type de retour doit être flexible ou au moins ne pas avoir besoin d'un énorme quantité de casting.

Est-ce que quelqu'un a une bonne idée sur la façon de mettre en œuvre cela?

+8

Pas une idée très brillante d'avoir une classe nommée Tâche (et êtes-vous sûr de ne pas réinventer la roue? [Tâche de classe] (https://msdn.microsoft.com/en-us/library/system. threading.tasks.task (v = vs.110) .aspx)) – Steve

+5

Si vous n'êtes pas sûr de la raison pour laquelle Steve a écrit son commentaire, voici une référence à un rôle central de classe jouant dans la façon dont C# gère l'exécution asynchrone: [' Task'] (https://msdn.microsoft.com/en-us/library/system.threading.tasks.task%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396). – dasblinkenlight

+0

Non, le nom Tâche n'était qu'un exemple. C'est en fait une autre classe avec plus de choses, ce qui n'influence pas le problème – Curunir

Répondre

0

..qui signifie que le type de retour doit être flexible - signifie que l'héritage n'aidera pas. Avec la méthode d'héritage, la "signature" devrait être la même.

Vous pouvez introduire un type général retourné, puis l'utiliser pour la signature de votre méthode.

public class Result 
{ 
    public object Value {get; set;} 
} 

public interface IYourTask 
{ 
    Result Execute(); 
} 

public class StringManipulationTask 
{ 
    public Result Execute() 
    { 
     // do something 
     return new Result("resultofManipulation"); 
    } 
} 

public class NoReturnDataTask 
{ 
    public Result Execute() 
    { 
     // do something 
     return new Result(); // with no data - "empty result" 
    } 
} 

Basé sur le comportement du « résultat » vous pouvez introduire Result comme l'abstraction et ont propre mise en œuvre d'un comportement différent. Résumé - Pour utiliser toutes les tâches de la même manière «générale», vous devez envelopper toutes les tâches dans le même format/la même signature.

+0

Ok j'ai oublié de dire que certains ne renvoient pas un résultat, mon mauvais. – Curunir

+0

@Curunir, dans le cas où la tâche ne retourne pas, vous pouvez retourner le résultat "vide" – Fabio