2017-07-07 35 views
0

我想存儲一些通用函數以供稍後執行。問題出現在關於函數的論點上。對於不同的類型,我想創建和存儲相同的泛型函數委託,但我不能這樣做。下面是我的版本獲取函數的類;存儲函數模板

public delegate void CGTaskHandler1<T>(T value) where T : IControllerBase; 

public class CGTask 
{ 

    private CGTaskHandler1<IControllerBase> Aksiyon; 
    private IControllerBase param; 

    public void RegisterCGTask(CGTaskHandler1<IControllerBase> aFunc, IControllerBase aParam) 
    { 
     Aksiyon = aFunc; 
     param = aParam; 
    } 


    public void ExecuteCGTask() 
    { 
     try 
     { 
      Aksiyon(param); 
     } 
     catch (Exception ex) 
     { 
      Logger.SetLog("action execution failed ", LogType.error, ex.Message) 
     } 
    } 
} 

由此類我使用的接口,用於收集下同名每個不同類型的參數,但是編譯器要完全相同的類型和接口類型似乎沒有幫助。

private void LoadScene(cScene ascn) 
    { 
     ascn.LoadScene(); 
    } 

    public CGTask GetTask(String btnName) 
    { 
     CGTask back = new CGTask(); 
     CGTaskHandler1<IControllerBase> alomelo = LoadScene; // type mismatch 
     back.RegisterCGTask(alomelo, thisScene); 

     //CGTask2<cScene> back = new CGTask2<cScene>(); 
     //CGTaskHandler1<cScene> alomelo = LoadScene; 
     //back.RegisterCGTask(alomelo, thisScene); 

     return back; 
    } 

,所以我改變了我的cgtask類泛型類,因此,參數類型是當類實例化自定。

public class CGTask2<T> 
{ 

    private CGTaskHandler1<T> Aksiyon; 
    private T param; 

    public void RegisterCGTask(CGTaskHandler1<T> aFunc, T aParam) 
    { 
     Aksiyon = aFunc; 
     param = aParam; 
    } 

    public void ExecuteCGTask() 
    { 
     try 
     { 
      Aksiyon(param); 
     } 
     catch (Exception ex) 
     { 
      Logger.SetLog("action execution failed ", LogType.error, ex.Message); 
     } 
    } 
} 

然而,當我想將它們收集到一個列表中時,我面對同樣的問題。

List<CGTask2<IControllerBase>> gorevler = new List<CGTask2<IControllerBase>>(); 
    gorevler.Add(new CGTask2<cScene>()); // type mismatch 

我需要一種方法來保持對象的功能。每次我使用通用函數委託時,我需要指定類型,並且通用函數的類型不可轉換。有沒有辦法做到這一點,保持對函數的引用並將這些引用作爲對象進行收集?

public interface IControllerBase 
    { 
     void GetTalker(); 
     void InitiliazeTalker(); 
    } 

    public class cControllerBase : IControllerBase 
    { 
     public cControllerBase Parent=null; 

     protected Talker tk; 

     protected void GetTalker() 
     { 
      tk = Talker.Instance; // not initialized yet 
     } 

     protected void InitiliazeTalker() 
     { 
      tk.InitializeReTalk(); 
     } 

    } 

    public class cScene : cControllerBase, IControllerBase 
    { 
     public String ID; 
     public String ScenePath; 
     public String SceneName; 
     public int Slot; 
     public String DBParent; 
     public List<cAnimation> Animations; 
     public List<cExport> Exports; 
     public Boolean IsActive; 

     public cScene() 
     { 
      GetTalker(); 
      Animations = new List<cAnimation>(); 
      Exports = new List<cExport>(); 
      // ID = Guid.NewGuid().ToString(); 
      IsActive = false; 
     } 

     public Boolean ParseXml(String pXmlPath) 
     { 
      if (String.IsNullOrEmpty(pXmlPath)) return false; 
      XmlDocument xdoc = new XmlDocument(); 
      XmlNodeList anims = null; 
      XmlNodeList exps = null; 
      try 
      { 
       xdoc.Load(pXmlPath); 
       anims = xdoc.SelectNodes("//scene_description/animations/animation"); 
       exps = xdoc.SelectNodes("//scene_description/exports/export"); 
      } 
      catch (Exception ex) 
      { 
       Logger.SetLog("xml parse error", LogType.error, ex.Message); 
       return false; 
      } 


      cAnimation tempanim; 
      cExport tempexport; 

      foreach (XmlNode x in anims) 
      { 
       tempanim = new cAnimation(); 
       foreach (XmlAttribute y in x.Attributes) 
       { 
        switch (y.Name) 
        { 
         case "name": 
          { 
           tempanim.AnimationName = y.Value; 
           break; 
          } 
         case "duration": 
          { 
           tempanim.AnimationDuration = Globals.GetIntValue(y.Value); 
           break; 
          } 
         case "end_animation_time": 
          { 
           tempanim.AnimationEndTime = Globals.GetIntValue(y.Value); 
           break; 
          } 
         case "start_animation_time": 
          { 
           tempanim.AnimationStartTime = Globals.GetIntValue(y.Value); 
           break; 
          } 
        } 
       } 
       tempanim.Parent = this; 
       Animations.Add(tempanim); 
      } 

      foreach (XmlNode x in exps) 
      { 
       tempexport = new cExport(); 
       foreach (XmlAttribute y in x.Attributes) 
       { 
        switch (y.Name) 
        { 
         case "name": 
          { 
           tempexport.ExportName = y.Value; 
           break; 
          } 
         case "type": 
          { 
           switch (y.Value) 
           { 
            case "String": 
             { 
              tempexport.ExportType = ExportDataType.tString; 
              break; 
             } 
            case "File": 
             { 
              tempexport.ExportType = ExportDataType.tFile; 
              break; 
             } 
            case "Float": 
             { 
              tempexport.ExportType = ExportDataType.tFloat; 
              break; 
             } 
            case "Int": 
             { 
              tempexport.ExportType = ExportDataType.tInt; 
              break; 
             } 
            case "Bool": 
             { 
              tempexport.ExportType = ExportDataType.tBool; 
              break; 
             } 
           } 
           break; 
          } 
         case "value": 
          { 
           tempexport.ExportValue = y.Value; 
           break; 
          } 
        } 
       } 
       tempexport.Parent = this; 
       Exports.Add(tempexport); 
      } 


      return true; 

     } 

     public void ActivateScene() 
     { 
      tk.ActivateScene(Slot, SceneName); 
      IsActive = true; 
     } 

     public void DeactivateScene() 
     { 
      // to do 
      // tk'dan aktif scene listesi yapıp kontrol edebiliyor musun? 
      tk.DeactivateScene(Slot); 
      IsActive = false; 
     } 

     public Boolean IsSceneLoaded() 
     { 
      Boolean back = false; 
      back = tk.IsSceneLoaded(SceneName); 
      return back; 
     } 

     public void LoadScene() 
     { 
      tk.LoadScene(SceneName); 
     } 

     public void UnloadScene() 
     { 
      tk.UnloadScene(SceneName); 
     } 

     public void SetSceneName(String strxmlPath) 
     { 
      ScenePath = strxmlPath; 
      SceneName = strxmlPath.Substring(0, strxmlPath.LastIndexOf('\\')); 
      SceneName = SceneName.Replace('\\', '/'); 
      SceneName = SceneName.Substring(SceneName.IndexOf("Projects") + 9); 

     } 
    } 
+0

什麼是'cScene'? – DavidG

+0

我添加了cScene類定義 –

回答

0

CGTask2<cScene>是一個完全不同的類型CGTask2<IControllerBase>,你無法相提並論兩個。你將不得不有一個列表,例如,ITask,並使CGTask2實現。例如:

public interface ITask {} 

public class CGTask2<T> : ITask 
{ 
    //snip 
} 

現在你可以這樣做:

List<ITask> gorevler = new List<ITask>(); 
gorevler.Add(new CGTask2<cScene>()); 
+0

謝謝你的幫助 –