2010-10-27 6 views
2

J'ai un peu difficile d'expliquer mon problème, parce que je ne suis pas bon en anglais: |! J'ai le code suivantAppel d'une fonction d'une classe "enfant" référant la classe principale

namespace StighyGames.MyGames { 
public class MyGames 
{  
... 
... 
    CarClass myCar = new CarClass(...); 

    Main() { 
    MyGames game = MyGames(...); 
    } 
} 

jeu est mon objet "principal" (ma demande).

Dans mon CarClass j'ai un code ...

Maintenant, à l'intérieur maVoiture (objet) je voudrais appeler une fonction (une méthode) contenait les principales myGames de classe .. la méthode « de GameOver ». Ceci, parce que, si ma voiture "explose", je dois appeler la méthode GameOver. Mais la méthode GameOver ne peut pas être "enfant" de myCar ... car GameOver est une méthode du jeu ... Ok .. j'espère être expliqué, ma question est: "Je ne sais pas comment appeler un méthode de la classe d'objet principale "..

Nous vous remercions de votre aide!

+0

Merci à tous! Je ne sais pas laquelle marquer comme la "meilleure" réponse !!! ;) Tous sont corrects, bons et bien expliqués !!! – stighy

Répondre

1

Comme tout le monde a répondu, vous avez plusieurs options. Mais toutes les options ne sont pas également bonnes.
Voici ma liste.

1) Ajouter un événement à l'objet Car et laisser le jeu s'enregistrer.
2) Passer un délégué à l'objet Car
3) Passer à l'objet Car une référence à un jeu
4) Utiliser l'appel statique.

Toute la réponse, sauf la première sont « mauvaises »)

Voici le code. J'utilise C# 4.0

public class Car 
{ 
    public event Action<Car> Explode; 

    private void OnExplode() 
    { 
     Explode(this); 
    } 
} 

public class Game 
{ 
    private Car car; 


    public Game() 
    { 
     car = new Car(); 
     car.Explode += new Action<Car>(NotifyExplosion); 
    } 

    private void NotifyExplosion(Car car) 
    { 
     Console.WriteLine("{0} is exploded", car.ToString()); 
     GameOver(); 
    } 

    private void GameOver() 
    { 
     Console.WriteLine("GAME OVER"); 
    } 

    static void Main(string[] args) 
    { 
     Game game = new Game(); 
    } 

} 
+0

Juste une pomme de discorde mineure, je ne pense pas que tous les autres moyens soient nécessairement mauvais. Juste le plus probablement mauvais. Si, par exemple, chaque objet Car doit provoquer une action externe lors d'un crash, et que vous souhaitez explicitement empêcher plus (ou moins) qu'un seul abonné potentiel, car une voiture ne devrait jamais être dans plus d'un jeu, vous devez pourrait vouloir utiliser un délégué, et peut-être même l'inclure en tant que paramètre de constructeur requis. Ce serait plus efficace et la construction correspond mieux à la fonctionnalité prévue. –

+0

Oui, bien sûr, tout dépend de ce que vous voulez réaliser;) – bonfo

1

Vous pouvez:

  1. Modifier votre pour contenir une référence CarClass classe (ce qui devrait vraiment être renommé Car) au jeu auquel il appartient.

  2. Créez un événement dans la classe Car appelé Explode. La classe Game peut alors s'enregistrer pour l'événement Explode et s'assurer que la méthode GameOver() est appelée depuis ce gestionnaire.

1

Vous pouvez utiliser le motif de conception Singleton sur votre classe principale.

Ou vous pouvez annuler le problème et implémenter un CheckGameOver dans MyGames, qui interrogerait la voiture pour son état. Ce serait ma méthode préférée, car elle réduit les dépendances.

1

Vous pouvez transmettre une référence à votre instance MyGames dans votre instance CarClass, c'est la référence 'parent'. Bien que je pense que vous pourriez mieux architecturer votre jeu en utilisant des événements et des délégués, rien ne vous empêche d'appeler une méthode sur l'objet parent.

5

Vous avez plusieurs options.

1) Créez un event dans CarClass et capturez-le dans MyGames.

2) Utilisez un delegate et passer la référence de fonction pour objet CarClass

3) Ajouter une propriété à CarClass de types myGames (disons appelé « propriétaire »), et après avoir créé CarClass, affecter « ce » à it: myCar.Owner=this. Vous avez donc créé une référence dans l'objet CarClass à son créateur, et le code dans CarClass peut directement accéder aux méthodes de son propriétaire.

Ce qui est le meilleur dépend de la situation et de la façon dont ces objets seront utilisés. Un événement est probablement préféré, car il offre le plus de flexibilité. Un délégué est moins flexible et plus efficace qu'un événement, même si ses objectifs sont vraiment différents. (Un événement est vraiment une extension d'un délégué). Le dernier est probablement la pire forme, généralement, car il lie étroitement les objets, mais il a un temps et un lieu.

est ici # 1

public class CarClass 
{ 
    // A delegate is a pointer to a function. Events are really a way of late 
    // binding delegates, so you need to one of these first to have an event. 
    public delegate void ExplodedHandler(CarClass sender); 
    // an event is a construct which is used to pass a delegate to another object 
    // You create an event based for a delegate, and capture it by 
    // assigning the function reference to it after the object is created. 
    public event ExplodedHandler Exploded; 
    protected void CarCrash() 
    { 
     ... do local stuff 
     // Make sure ref exists before calling; if its required that something 
     // outside this object always happen as a result of the crash then 
     // handle the other case too (throw an error, e.g.)/ 
     // See comments below for explanation of the need to copy the event ref 
     // before testing against null 
     ExplodedHandler tempEvent = Exploded; 
     if (tempEvent != null) { 
     tempEvent(this); 
     } 
    } 
} 
public class MyGames 
{  
... 
... 
    CarClass myCar = new CarClass(...); 
    myCar.Exploded += new ExplodedHandler(GameOver); 
    Main() { 
    MyGames game = MyGames(...); 
    } 
    void GameOver(CarClass sender) { 
    // Do stuff 

    } 
} 
+0

+1 pour l'événement. C'est l'option la plus raisonnable –

+2

Je pense que GameOver est plus une responsabilité de jeu que de voiture. La voiture devrait juste dire: "Je suis explosé!". – bonfo

+0

Très bon point, les événements sont mal nommés ... correctifs. –

Questions connexes