存储功能模板

时间:2017-07-07 09:33:04

标签: c# generics delegates

我想存储一些通用函数以便以后执行。问题出现在函数的论证上。对于不同的类型,我想创建和存储相同的泛型函数委托,但我不能这样做。下面是我获取函数的类版本;

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

        }
    }

1 个答案:

答案 0 :(得分:0)

CGTask2<cScene>CGTask2<IControllerBase>的类型完全不同,您不能将两者等同起来。您必须有一个列表,例如ITask和make CGTask2实现它。例如:

public interface ITask {}

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

现在你可以这样做:

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