使用嵌套类型参数和递归(C#)

我试图利用嵌套的参数类型,这似乎是非法的。 我宁愿将递归函数保持在下面,以便我不必复制逻辑。 但是我嵌套使用会使CLR非常不高兴(请参阅代码中列出的错误)。 MyMethod中的逻辑不可避免地创建ActionAction两种类型的委托。 有没有办法改变下面的代码来实现我的目标? 关于使用类型参数(即 )的一般限制是什么? 也许类型安全性的丧失是禁止此类代码的原因?

ClassA-> ClassB(inherets)

 public void MyMethod(Action actionDelagate) where Ttype : ClassB { // Recursive Call with Ttype=ClassA if (Only able create Class A delagate) MyMethod(v => doStuff) // Recursive Call with Ttype=ClassB if (Only able create Class B delagate) MyMethod(v => doStuff) // Utilize Delagate if (TypeOf(Ttype) == ClassA) actionDelagate(new Class A) // Expecting type "Ttype" else actionDelagate(new Class B) // Expecting type "Ttype" } 

谢谢,aidesigner

你正在使用的where子句没有意义。 如果您知道该函数需要ClassB,为什么不说myMethod (Action actionDelegate)?

如果你想使用一些通用的Ttype,你需要说出Ttype:new()的位置,然后在调用actionDelagate时说新的Ttype()。 那应该做你想要的。

 public void MyMethod(Action actionDelagate) where Ttype : new() { MyMethod(v => doStuff) actionDelagate(new Ttype()) // Expecting type "Ttype" } 

我意识到我试图抽象问题使我很难理解我的限制。 下面是一个接近实现的示例。 下面的注释应该有所帮助,因此您不必深入研究.NET类。

  • Srgs *是命名空间“System.Speech.Recognition.SrgsGrammar”中的.NET类
  • SrgsElement派生自SrgsItem
  • C#不支持“ generics差异 ”! 这意味着,与你的直觉相反,即使SrgsItem“是一个”SrgsElement,递归调用也不能传入“Action”。

我能够通过创建一个以Arg1为Action的CreateSrgsNodes重载来解决我的问题。 然而,这意味着在两个未通过气味测试的地方保持相同的代码。 如果有人可以改进,请certificate一个新的答案。

  public void CreateSrgsNodes(Action addSrgsChild, CurrentNode) { foreach (GmlModel gmlModel in gmlModels) { if () { var srgsOneOf = new SrgsOneOf(); addSrgsChild(srgsOneOf); //Note: Arg1 is type SrgsElement CreateSrgsNodes(srgsOneOf.Add, CurrenNode.getChild); } if () { var srgsOneOf = new SrgsOneOf(); addSrgsChild(srgsOneOf); //Note: Arg1 is type SrgsItem (FAILS without an overload) CreateSrgsNodes(Action, CurrentNode)) CreateSrgsNodes(srgsOneOf.Add,CurrenNode.getChild); created } } }