Unity3D:使用Delegate返回值

时间:2016-03-23 17:01:17

标签: c# unity3d delegates return-value

我希望能够从我的委托中的所有方法获取返回值。这是我用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;
        }
    }

如您所见,委托的返回类型为int。然后我放入我的委托的方法也有返回类型int。其中一个返回1,另一个返回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);
    }
}

3 个答案:

答案 0 :(得分:3)

好吧,在&#34;常规&#34;在.NET框架中,您可以使用// Note: do all of this after checking that unitSpawn is non-null... var results = unitSpawn.GetInvocationList() .Cast<UnitEventHandler>() .Select(d => d(_unit)) .ToList(); 。例如,将其与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);
}

我不知道这是否可以与Unity合作,但我希望它会......

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

brushed

答案 1 :(得分:1)

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

您可以使用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>;
    }
} 

答案 2 :(得分:0)

谢谢你们!它有很多帮助。我用下面的代码解决了它:

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);
        }
    }
}