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