此问题在此处已有答案:
(17个答案)
Retrieving the calling method name from within a method [duplicate](7个答案)
七年前就关门了。
我想知道是否有一种方法可以在运行时确定调用它的类型。
[UPD2]对于这个特定的例子,我只对调用者的Type感兴趣,而不是方法的名称,所以,其他类似的问题,如How can I find the method that called the current method?或Retrieving the calling method name from within a method,并不能解决我的问题。
为了简单起见,假设我有一个名为AnimalContainer
的类,在初始化时,它的构造函数将接收一个允许类型的列表:允许将动物登记到容器中的类型。
这个类(类似于IoC容器)的目标是为任何希望检索特定动物示例的类型充当容器。限制是只有任意类型集才能将动物注册到容器。然后,如果不允许的类型调用该方法,该方法将返回InvalidOperationException
需要类型或对象参数:
void RegisterAnimal(Type callerType, Animal animal) {...}
// Or
void RegisterAnimal(object invoker, Animal animal) {...}
这些方法不起作用,因为调用者没有被限制指定自己的类型(或示例)。
// Inside class A:
animalContainer.RegisterAnimal(typeof(B), anyAnimal);
[UPD1]我已经看到很多回答,说这似乎是一个很糟糕的方法。如果你这样认为,你会建议另一种方法吗?一般来说,我试图实现的是防御性编码。我当然可以,按照约定,允许注册容器中的动物的类型集。会发生什么,是任何其他开发人员,谁不知道这个约定,尝试在一个类中注册一个动物不应该这样做吗?它会做一些设计没有预料到的事情,所以,最有可能的结果是引入一些错误。这只是我能找到的最简单的例子(AnimalContainer),但它可以扩展到大量的情况:
1.拥有一组将依赖项注册到IoC容器中的控制器类。
1.拥有一个MessageContainer,为不同类型之间的消息注册发布者和订阅者(分离事件订阅者应该知道谁在发布事件的事实)。然后指定只有一组类型可以发布给定的消息。例如:任何类都可以侦听NewAnimalArrive消息,但只有一组特定的类可以激发该事件。
3条答案
按热度按时间rqenqsqc1#
您可以使用反射来访问堆栈跟踪,但这很慢,而且在某些情况下,如果JIT由于内联而跳过了一些堆栈帧,我也不会感到惊讶。
一种选择是使方法成为内部方法,并且只将“允许的”类型包含在同一程序集中;或者使方法成为私有方法,并且只将“允许的”类型作为嵌套类型包含在外部类型中。
没有比这更细粒度的了--如果您需要程序集中“允许的”类型以外的类型,您应该考虑您的信任模型......您对程序集中的其他代码有多大的控制权?如果您不信任的其他人可以更改该代码,那么游戏就结束了,他们可以撤消您添加的任何保护。
如果你试图防止 * 意外 * 做错事,你可以使用罗斯林代码诊断,潜在的...但基本上只有到目前为止,这种事情可以带你。
jecbmhm32#
stackTrace =新的堆栈跟踪();控制台。写入行(堆栈跟踪。获取帧(1)。获取方法()。名称);
oymdgrw73#
这个要求听起来很糟糕,我想你最好换种方式。也就是说,下面的代码通常可以让你得到调用者的类型。我强烈建议你不要用它,因为有很多原因(包括它很慢,容易出错,我有没有提到它很慢?)
在使用下面的代码之前,请考虑一下您正在做什么。
代码基于NLog的源代码