Как использовать строку делегата, подписанную на 2 метода - PullRequest
0 голосов
/ 22 мая 2018

У меня есть 2 класса C #, один из них имеет строковый делегат, а другой подписывает функцию на этот делегат.

Мой вопрос: я хочу объединить две вызываемые строковые функции из делегата, а не выбиратьслучайное возвращаемое значение между ними

delgatesystem.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class delegatesystem : MonoBehaviour {

public delegate string MyDelegate();
public static event MyDelegate MyEvent;
string GameObjectsNames = "";

void Update ()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (MyEvent != null)
         {
           GameObjectsNames +=  MyEvent();
         }
       }
    }
}

Delegatesave.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class delegatesave : MonoBehaviour {

void Start ()
{
    delegatesystem.MyEvent += DelegateFunction;
}

string DelegateFunction()
{
    return gameObject.name;
}
}

примечание: delgatesave.csприкреплен к 2 игровым объектам.

1 Ответ

0 голосов
/ 22 мая 2018

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

Если многократный многоадресный делегат вызывается с несколькими подписчиками, всегда возвращается возвращаемое значение последнего подписанного метода.

Но после всех васможет сделать что-то вроде этого:

string[] objectNames = MyEvent.GetInvocationList().Cast<MyDelegate>().Select(del => del()).ToArray();

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

public class PopulateNamesEventArgs : EventArgs
{
    private List<string> names = new List<string>();
    public string[] Names => names.ToArray();
    public void AddName(string name) => names.Add(name);
}

А затем в вашем классе:

public event EventHandler<PopulateNamesEventArgs> MyEvent;

protected virtual void OnMyEvent(PopulateNamesEventArgs e) => MyEvent?.Invoke(this, e);

Вызов:

var e = new PopulateNamesEventArgs();
OnMyEvent(e);
string[] objectNames = e.Names; // the result is now populated by the subscribers

Подписка:

void Start()
{
    delegatesystem.MyEvent += DelegateFunction;
}

void DelegateFunction(object sender, PopulateNamesEventArgs e)
{
    e.AddName(gameObject.name);
}
...