Вызов функции из «дочернего» класса со ссылкой на основной класс - PullRequest
2 голосов
/ 27 октября 2010

Мне сложно объяснить мою проблему, потому что я не очень хорошо знаю английский: |! У меня есть следующий код

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

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

Игра - это мой «основной» объект (мое приложение).

В моем CarClass у меня есть код ...

Теперь внутри myCar (объект) я хотел бы вызвать функцию (метод), содержащий основной класс MyGames .. метод "GameOver". Это потому, что, если моя машина "взорвется", я должен вызвать метод GameOver. Но метод GameOver не может быть «дочерним» для myCar ... потому что GameOver - это метод игры ... Хорошо ... надеюсь, что объяснение, мой вопрос: "Я не знаю, как вызвать метод класса основного объекта" ..

Спасибо за вашу помощь!

Ответы [ 5 ]

5 голосов
/ 27 октября 2010

У вас есть несколько вариантов.

1) Создайте event в CarClass и сохраните его в MyGames.

2) Используйте delegate и передайте ссылку на функцию в объект CarClass

3) Добавьте свойство в CarClass типа MyGames (скажем, с именем «Владелец») и после создания CarClass присвойте ему «this»: myCar.Owner=this. Итак, вы создали ссылку в объекте CarClass на его создателя, и код в CarClass может напрямую обращаться к методам его владельца.

Что лучше, зависит от ситуации и от того, как эти объекты будут использоваться. Событие, вероятно, предпочтительнее, так как оно предлагает наибольшую гибкость. Делегат менее гибок и более эффективен, чем мероприятие, хотя на самом деле он служит немного другим целям. (Событие действительно является продолжением делегата). Последний, вероятно, является наихудшей формой, поскольку он тесно связывает объекты, но у него есть время и место.

Вот # 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

  }
}
1 голос
/ 27 октября 2010

Поскольку все ответили, у вас есть несколько вариантов.Но не все варианты одинаково хороши.
Вот мой список.

1) Добавьте событие к объекту Car и позвольте игре зарегистрироваться на нем.
2) Передайте делегата на Carобъект
3) передать объекту Car ссылку на игру
4) использовать статический вызов.

Все ответы, кроме первого, "плохие";)

Здесь код.Я использую 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();
    }

}
1 голос
/ 27 октября 2010

Вы можете использовать шаблон проектирования Singleton в своем основном классе.

Или вы можете устранить проблему и внедрить CheckGameOver в MyGames, который будет опрашивать автомобиль на предмет его состояния.Это был бы мой предпочтительный метод, так как он уменьшает зависимости.

1 голос
/ 27 октября 2010

Вы можете передать ссылку на ваш экземпляр MyGames в ваш экземпляр CarClass, это ссылка на «родитель».Хотя я думаю, что вы могли бы лучше спроектировать свою игру, используя события и делегаты, ничто не мешает вам вызывать метод родительского объекта.

1 голос
/ 27 октября 2010

Вы можете:

  1. Изменить свой класс CarClass (который действительно должен быть переименован в Car), чтобы он содержал ссылку на игру, к которой он принадлежит.

  2. Создайте событие в классе Car с именем Explode.Класс Game может затем зарегистрироваться для события Explode и убедиться, что метод GameOver() вызывается из этого обработчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...