Reputation: 7
I have 2 C# classes one of them has a string delegate and the other subscribes an function to that delegate.
My question is I want to combine the two called string functions from the delegate instead of choosing the return value between them randomly
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;
}
}
note: the delgatesave.cs is attached to 2 gameobjects.
Upvotes: 0
Views: 307
Reputation: 18033
First of all, creating events with non-void delegates is an antipattern. Events are typically used with potentially more subscribers.
If a non-void multicast delegate is invoked with multiple subscribers, always the return value of the last subscribed method is returned.
But after all you can do something like this:
string[] objectNames = MyEvent.GetInvocationList().Cast<MyDelegate>().Select(del => del()).ToArray();
However, a better solution would be to use more conventional events:
public class PopulateNamesEventArgs : EventArgs
{
private List<string> names = new List<string>();
public string[] Names => names.ToArray();
public void AddName(string name) => names.Add(name);
}
And then in your class:
public event EventHandler<PopulateNamesEventArgs> MyEvent;
protected virtual void OnMyEvent(PopulateNamesEventArgs e) => MyEvent?.Invoke(this, e);
Invokation:
var e = new PopulateNamesEventArgs();
OnMyEvent(e);
string[] objectNames = e.Names; // the result is now populated by the subscribers
Subscription:
void Start()
{
delegatesystem.MyEvent += DelegateFunction;
}
void DelegateFunction(object sender, PopulateNamesEventArgs e)
{
e.AddName(gameObject.name);
}
Upvotes: 2