2016-03-23 40 views
0

我希望能夠從我的委託中獲取所有方法的返回值。這是我用c#編寫的代碼。Unity3D:使用委託返回值

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

那麼,在「常規」的.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(); 

我不知道是否不加思索將與團結的工作,但我希望它會...

:例如,要結合起來,與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); 
} 
+0

的LINQ不工作的統一,但其中的一件事情,統一開發者建議迴避。據報在iOS上失敗。不確定是否仍有問題。 – Everts

+0

@fafase:被編輯爲顯示非LINQ版本。 –

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

謝謝你們!它幫助了很多。我有如下因素代碼解決了這個問題:

和:

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