Возможно ли добавить метод к классу в коллекции?

#c# #.net #xna

#c# #.net #xna

Вопрос:

Я пытаюсь создавать страницы в XNA с помощью кнопок и ползунков и перепробовал несколько идей, но, похоже, я застрял между сохранением «объектно-ориентированного» подхода и сохранением того, чтобы кнопки и ползунки оставались полезными, не добавляя многого к фактическим классам «Button» и «Slider».

Итак, мне интересно, есть ли волшебный способ создать экземпляр класса Button, а затем добавить метод или какую-то ссылку на метод, чтобы я мог выполнить итерацию через мою коллекцию кнопок или ползунков и, если один из них «нажат», выполнить конкретный метод, связанный с этой кнопкой?

Предпочтительно я хотел бы написать методы один за другим в родительском классе, который представляет экран, который я рисую в данный момент.

Фантастический пример кода:

 class Room // Example class to manipulate 
{ 
    public bool LightSwitch; 
    public void Leave() { /* Leave the room */ } 
} 

class Button 
{   // Button workings in here 
    public bool GotPressed(/*click location */) 
    { /* If click location inside Rect */ return true; } 

    public void magic() {} // the method that gets overidden 
} 

public class GameScreen 
{ 
    public Room myRoom; 
    private List<Button> myButtons; 

    public GameScreen() 
    { 
        myRoom = new Room(); 
        myRoom.LightSwitch = false; 
        List<Button> myButtons = new List<Button>(); 

        Button B = new Button(); 
        // set the buttons rectangle, text etc 
        B.magic() == EscapeButton(B); 
        myButtons.Add(B); 

        Button B = new Button(); 
        B.magic() == SwitchButton(B); 
        myButtons.Add(B); 
    } 

    public void Update() // Loop thru buttons to update the values they manipulate 
    {   foreach (Button B in myButtons) 
        { if(B.GotPressed(/*click*/)) { B.magic(B) } }} 
        // Do the specific method for this button  

    static void EscapeButton(Button b) 
    { myRoom.Leave(); } 

    static void SwitchButton(Button b) 
    { myRoom.LightSwitch = true; } 
} 
  

Ответ №1:

Я думаю, вы ищете либо делегаты для событий for. Я бы рекомендовал использовать события здесь:

Сначала создайте общедоступное событие со всем, что есть в вашем классе, например:

 public delegate void ClickedHandler(object sender, EventArgs e);
public event ClickedHandler Clicked;
private void OnClidked()
{
  if (Clicked != null)
  {
     Clicked(this, EventArgs.Empty);
  }
}
  

Затем вы создаете метод в классе button, который проверяет, был ли на нем нажат

 public void CheckClick(Vector2 click)
{
   if (/* [i am clicked] */)
   {
     OnClicked();
   }
}
  

Вне кнопки вы можете подписаться на событие clicked следующим образом:

 var b = new Button();
b.Clicked  = new ClickedHandler(b_Clicked);

/* [...] */

private void b_Clicked(object sender, EventArgs e)
{
   /** do whatever you want when the button was clicked **/
}
  

Чтобы узнать больше о событиях, перейдите сюда: http://www.csharp-station.com/Tutorials/lesson14.aspx . Надеюсь, это поможет.

Комментарии:

1. Это то, что я хотел, я просто еще не видел хорошего примера событий, примеры msdn, похоже, добавляют много шума и скрывают более практическое применение! Большое спасибо!

Ответ №2:

C # имеет методы расширения, которые могут соответствовать вашим потребностям.

Методы расширения определены в некотором статическом классе со специальным синтаксисом. Примером этого может быть следующее:

 public static char GetLastChar(this string some) 
{
       return some[some.length - 1];
}

string a = "hello world";
char someChar = a.GetLastChar();
  

Вы можете узнать больше здесь:

Комментарии:

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

2. Важно, чтобы вы прочитали ответ. Прочитав ссылку Msdn, вы обнаружите, что метод расширения ведет себя как экземпляр.

Ответ №3:

У меня смутное представление о требованиях игрового программирования, но недавно я видел презентацию об этом фреймворке — http://dynobjects.codeplex.com/Похоже, ti решает аналогичную, если не ту же проблему.

Комментарии:

1. Спасибо, к сожалению, презентация — Office 2010, а код — для studio 2010 (я использую Express, который бесплатный).

2. Я почти уверен, что вы можете создать библиотеку с помощью Express. Похоже, что другие проекты — это просто демонстрация. Вы также должны уметь создавать проект WPF с помощью Visual C # Express.