Unity3D:Return 值与委托

Unity3D: Return value with a Delegate

我希望能够从我的委托中的所有方法中获取 return 值。这是我用c#写的代码。

    using UnityEngine;
    using System.Collections;

    public static class DelagetsAndEvents {

        public delegate int UnitEventHandler(string _unit);
        public static event UnitEventHandler unitSpawn;

        public static int UnitSpawn(string _unit)
        {
            if(unitSpawn != null)
            {
                unitSpawn(_unit);
            }

            // here I want to return 1 + 2 from Planet/UnitSpawn and SolarSystem/UnitSpawn
            // is it possible to run a foreach on every method in the delegate and add their returns?

            return (method 1's return value) + (method 2's return value) (Or both seperately, that would be even better)
        }
    }

    public class Planet {

        public Planet()
        {
            DelagetsAndEvents.unitSpawn += UnitSpawn;
        }

        int UnitSpawn(string _unit)
        {
            Debug.Log("yo");
            return 1;
        }
    }

    public class SolarSystem{

        public SolarSystem()
        {
            DelagetsAndEvents.unitSpawn += UnitSpawn;
        }

        int UnitSpawn(string _unit)
        {
            Debug.Log("bla");
            return 2;
        }
    }

如您所见,委托具有 return 类型的 int。然后我放入委托中的方法也有 return 类型的 int。其中一个 return 1,另一个 return 2。有没有办法将这些结果发送到我执行委托的位置?那将在这里:

using UnityEngine;
using System.Collections;

public class TestDelagets : MonoBehaviour {

    void Start () {
        SolarSystem s = new SolarSystem();
        Planet p = new Planet();
        string g = "";
        int i = DelagetsAndEvents.UnitSpawn(g);
        Debug.Log(i);
    }
}

嗯,在 "regular" .NET 框架中,您可以使用 Delegate.GetInvocationList。例如,将其与 LINQ 结合使用:

// Note: do all of this after checking that unitSpawn is non-null...

var results = unitSpawn.GetInvocationList()
                       .Cast<UnitEventHandler>()
                       .Select(d => d(_unit))
                       .ToList();

我不知道这是否适用于 Unity,但我希望它...

如果 LINQ 部分不起作用,您可以使用:

var invocations = unitSpawn.GetInvocationList();
var results = new int[invocations.Length];
for (int i = 0; i < invocations.Length; i++)
{
    results[i] = ((UnitEventHandler)invocations[i]).Invoke(_unit);
}

正如您提到的,您需要获得附加值或两个单独的值,我会选择不同的方法。

您可以使用 Linq,但 Unity 建议避免使用它。很可能是由于 C++ 和 C# 以及 GC 之间的序列化过程。

您可以将您的方法存储在一组操作中。然后你要么得到全额,要么用一个基本的foreach循环一个一个地得到。

public class DelegateContainer : IDisposable{
    private IList<Func<string, int>> container = null;
    public DelegateContainer(){
        this.container = new List<Func<string,int>>();
    }
    public void Dispose(){
         this.container.Clear();
         this.container = null;
    }
    public bool AddMethod(Func<string, int> func){
       if(func != null && this.container.Contains(func) == false){
           this.container.Add(func);
           return true;
       }
       return false;
    }
    public bool RemoveMethod(Func<string, int>func){
       if(func != null && this.container.Contains(func) == true){
           this.container.Remove(func);
           return true;
       }
       return false;
    }
    public int GetFullValue(){
       int total = 0;
       foreach(var meth in this.container){
           if(meth != null) { total += meth(""); }
       }
       return total;
    }
    public IEnumerable<int> GetAllValues(){
        IList <int> list = new List<int>();
        foreach(var meth in this.container){
           if(meth != null) { list.Add(meth("");); }
       }
       return list as IEnumerable<int>;
    }
} 

谢谢大家!它帮助了很多。我用下面的代码解决了它:

using UnityEngine;
using System.Collections;

public static class DelagetsAndEvents {

    public delegate int UnitEventHandler(string _unit);
    public static event UnitEventHandler unitSpawn;

    public static int[] UnitSpawn(string _unit)
    {
        if(unitSpawn != null)
        {
            unitSpawn(_unit);
        }



        System.Delegate[] funcs = unitSpawn.GetInvocationList();
        int[] TIntArray = new int[funcs.Length];

        for (int i = 0; i < funcs.Length; ++i)
        {
            TIntArray[i] = (int) funcs[i].DynamicInvoke(_unit);


        }

        return TIntArray;
    }
}

public class Planet {

    public Planet()
    {
        DelagetsAndEvents.unitSpawn += UnitSpawn;
    }

    int UnitSpawn(string _unit)
    {
        Debug.Log("yo");
        return 1;
    }
}

public class SolarSystem{

    public SolarSystem()
    {
        DelagetsAndEvents.unitSpawn += UnitSpawn;
    }

    int UnitSpawn(string _unit)
    {
        Debug.Log("bla");
        return 2;
    }
}

和:

using UnityEngine;
using System.Collections;
using System.Collections;

public class TestDelagets : MonoBehaviour {

    void Start () {
        SolarSystem s = new SolarSystem();
        Planet p = new Planet();
        string g = "";
        int[] i = DelagetsAndEvents.UnitSpawn(g);

        foreach(int f in i)
        {
            Debug.Log(f);
        }
    }
}