Вызов методов с разными параметрами

#c# #action

#c# #Экшен

Вопрос:

Я пытаюсь вызвать несколько методов с разными параметрами. Например, у меня есть UIElement, который я хочу переместить и удалить. В своем классе я реализую эти методы:

     public void Move(params object[] args)
    {
        Point lastpoint = (Point)Convert.ChangeType(args[0], typeof(Point));
        Point newpoint = (Point)Convert.ChangeType(args[1], typeof(Point));

        double left = Canvas.GetLeft(this)   (newpoint.X - lastpoint.X);
        double top = Canvas.GetTop(this)   (newpoint.Y - lastpoint.Y);

        Canvas.SetLeft(this, left);
        Canvas.SetTop(this, top);
    }

    public void Remove(params object[] args)
    {
        Canvas parent = this.Parent as Canvas;
        parent.Children.Remove(this);
    }
 

где:

  • аргументы в Move состоят из двух точек
  • аргументы в Remove должны быть нулевыми

Я использую класс для сбора всех моих событий из разных источников (мышь, касание, прыжок …), который называется EventLinker . Это довольно просто, поскольку оно просто содержит перечисление:

 public enum GestureKey
{
    OnClick, 
    OnDoubleClick, 
    OnLongClick,
    OnRightClick, 
    OnDoubleRightClick,
    OnLongRightClick,
    OnMove
};
 

Которые я могу использовать в словаре:

 private Dictionary<GestureKey, Action<object[]>> MyDictionary;
 

Методы Переместить и Удалить связаны двумя разными жестами:

 MyDictionary.Add(GestureKey.OnRightClick, Remove);
MyDictionary.Add(GestureKey.OnMove, Move);
 

Идея состоит в том, чтобы использовать этот словарь в нескольких прослушивателях, подключенных к одному и тому же UIElement, чтобы иметь возможность использовать мышь, сенсорный экран, LeapMotion … для управления моим приложением. Чтобы привести пример, когда я обнаруживаю щелчок в моем прослушивателе для моей мыши, я вызываю метод OnClick в моем словаре:

 if (MyDictionary.ContainsKey(GestureKey.OnClick))
{
    object[] args = { _lastPoint };
    Application.Current.Dispatcher.BeginInvoke(MyDictionary[GestureKey.OnClick], args);
}
 

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

Я хочу вызывать свои методы одинаково, даже если у них другой прототип. Если кто-нибудь знает, как это сделать, дайте мне знать!

РЕДАКТИРОВАТЬ: я думаю, проблема в словаре, который я использую, чтобы связать свои методы с моим перечислением. Он должен содержать методы с одинаковым прототипом. Есть ли какой-либо класс, который я мог бы использовать, который мог бы делать то же самое без той же проблемы с прототипом?

EDIT2: В идеале я должен иметь

     public void Move(Point lastpoint, Point newpoint)
    {
        double left = Canvas.GetLeft(this)   (newpoint.X - lastpoint.X);
        double top = Canvas.GetTop(this)   (newpoint.Y - lastpoint.Y);

        Canvas.SetLeft(this, left);
        Canvas.SetTop(this, top);
    }

    public void Remove()
    {
        Canvas parent = this.Parent as Canvas;
        parent.Children.Remove(this);
    }
 

Я думаю, проблема заключается в словаре, который я использую для привязки своих методов к GestureKey (см. Выше).

 private Dictionary<GestureKey, Action<object[]>> MyDictionary;
 

Класс dictionary позволяет мне связывать перечисление с любым типом, здесь Действие. Однако я должен указать, какие параметры принимает мое действие, что для меня является динамическим значением. Я думаю, я должен сделать что-то вроде:

 private Dictionary<GestureKey, Action<TYPELIST>> MyDictionary;
 

Но я не знаю, как это сделать. Я пытался использовать список, но у меня та же проблема, он запрашивает у меня что-то статическое. СПИСОК типов должен быть проинформирован динамически. И я не знаю, подходит ли для этого класс Dictionary, может быть, для этого есть лучший класс.

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

1. это все еще трудно понять. можете ли вы добавить какой-нибудь пример псевдокода того, что вы пытаетесь сделать? я согласен, что, вероятно, есть решение, как только вы его описали.

2. Вы хотите, чтобы сигнатура move была Move(Point old, Point new) и Remove() ? Это то, что ты пытаешься сказать?

3. я вижу, что вы пытаетесь там сделать. я посмотрю на это. некоторое время назад я тоже пытался делать подобные вещи

4. Спасибо. Я дам вам знать, если что-то найду.

Ответ №1:

Здесь немного другая разметка, но вы поймете это в любом случае. Для меня работает следующее:

     Dictionary<string, Delegate> _callbacks = new Dictionary<string, Delegate>();
    public MainWindow()
    {
        InitializeComponent();

        _callbacks.Add("move", new Action<Point, Point>(Move));
        _callbacks.Add("remove", new Action(Remove));

        Application.Current.Dispatcher.BeginInvoke(_callbacks["move"], new Point(5, 6), new Point(1, 3));
        Application.Current.Dispatcher.BeginInvoke(_callbacks["remove"]);
    }

    public void Move(Point something1, Point something2)
    {
    }

    public void Remove()
    {
    }
 

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

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

2. Лучше так, чем иначе ^^