【发布时间】:2020-10-12 19:12:15
【问题描述】:
首先,我完全意识到这有点奇怪,可能不是最佳的,但我仍在寻找一种方法来做到这一点:)
我有一个类似的课程:
public class Fruit {
public class Seed { }
public class Pit { }
}
然后我有一个继承的子类:
public class Avocado : Fruit {}
在代码的其他地方,我有一个字符串,上面写着“Avocado.Pit”,我需要得到那个确切的类型。
typeof(Fruit).GetNestedTypes() 实际上包含Seed 和Pit,但是typeof(Avocado).GetNestedTypes() 返回空,因为Seed 和Pit 在Fruit 上,而不是在Avocado 上(这是预期的:即使Avocado 继承自Fruit,GetNestedTypes() 的文档提到来自基类型的嵌套类被省略)。
如果我手动尝试new Avocado.Pit(); 或SomeGenericMethod<Avocado.Pit>();,它会按预期工作,所以看起来应该可以。
那么我该怎么做:
System.Type desiredType = System.Type.GetNestedTypesIncludingInherited("Avocado.Pit");
// desiredType.FullName would be Avocado.Pit, not Fruit.Pit.
我预计真正的方式将需要更多的箍才能跳过,但这没关系;这可能吗?非常感谢!
【问题讨论】:
-
您的代码中不存在任何名为
Avocado.Pit的类型。当你提到Avocado.Pit时,编译代码中真正引用的是Fruit.Pit,如果你不能检查反编译,Object.ReferenceEquals(typeof(Avocado.Pit), typeof(Fruit.Pit))会在运行时确认。您可以提到具有派生类型的限定名称的嵌套类型是编译器为了好玩而抛出的东西(可能是为了与成员保持一致),但在 .NET 类型系统中没有基础。现在,您可以编写一个无论如何都会输出Avocado.Pit的方法,但问题是您将如何处理它。 -
嗯,这很有趣,谢谢@JeroenMostert。我的目标是能够创建一个像
Prepare<T>() where T : Fruit {}这样能够动态获取坑类型的通用方法:所以如果我要通过Prepare<Avocado>(),在Prepare 方法的主体中我需要找到一种方法来做类似System.Type pitType = typeof(T).GetNestedTypesIncludingFromBase("Pit");的事情,希望到那时,pitType.FullName会是Avacado.Pit。 (我认为我的例子水果比喻有点崩溃哈哈,但希望这能告诉你我的意思)。再次感谢! :) -
但正如我指出的那样,这是不必要的,因为只有单一类型。你可以简单地写
Type pitType = typeof(Fruit.Pit)。是的,这也意味着您可以在任何您期望Peach.Pit的地方使用Avocado.Pit,无论这是否可取。如果你想要/需要这些类型的类型安全,你必须变得更棘手。正确的方法取决于这些类型应该完成的任务(除了抽象的Fruits)。一个实用的解决方案可能根本不涉及嵌套类型(至少不公开暴露的类型)。 -
再次感谢@JeroenMostert,这很有帮助!如果没有真正的方法来区分
Avocado.Pit或Peach.Pit,那么这可能行不通;不过,要回答您的问题,让我们回到Prepare<T>()方法:假设我会在某处致电Prepare<Avocado>()。在Prepare方法的主体中,我存储了给定的水果类型:Type fruitType = typeof(T); // Type Avocado然后我想以某种方式获得pitType(因为你的答案我现在意识到它不是唯一的):Type pitType = fruitType.GetAnyNestedType("Pit"); // Ideally this is Type Avocado.Pit -
对不起@JeroenMostert,房间用完了!该函数的最终目标是使用带有pit类型的通用函数:因此我可以手动将其编写为
Bury<Avacado.Pit>(),但我需要一种从上述类型动态执行此操作的方法。但是Bury<T>()函数假设了鳄梨核和桃核之间的区别……假设,如果可以使用构造的泛型类型 Avocado.Pit 调用 Bury,Bury 函数的主体是否有任何方法可以说明如果它来自鳄梨或桃子?
标签: c# reflection nested inner-classes system.reflection