I wish to know if there is a way for a method to determine, at run time, the type that invokes it.
[UPD2] For this particular case I'm interested in the Type of the caller only, not the name of the method, so, other similar questions like How can I find the method that called the current method? or Retrieving the calling method name from within a method doesn't solve my problem.
For the sake of simplicity, let's assume I have a class named AnimalContainer
.
At its initialization its constructor will receive a list of allowed types: The types who are allowed to register animals to the container.
The goal of this class (something like an IoC Container) is to serve as a container for any type who wish to retrieve an instance of a particular animal. The restriction is that only an arbitrary set of types should be able to register animals to the container. Then, if a non-allowed type calls the method, the method would return an InvalidOperationException
Expecting a Type or an object parameter:
void RegisterAnimal(Type callerType, Animal animal) {...}
// Or
void RegisterAnimal(object invoker, Animal animal) {...}
These won't work because the invoker is not restricted to specify its own type (or instance). For example:
// Inside class A:
animalContainer.RegisterAnimal(typeof(B), anyAnimal);
[UPD1] I've seen many answers stating that this seems so be a bad approach. If you consider so, would you suggest another way? In general terms, What I'm trying to achieve is to code defensively. I surely can have, by convention, the set of Types that are allowed to register animals in that container. What would happen, is any other developer, who aren't aware of this convetions, try to register an animal inside a class doesn't suppose to be doing that? It will be doing something that the design isn't expecting, so, most probably will end up by introducing some erros. This is just the simpler example I could find (The AnimalContainer) but it can be extended to a huge set of situations:
Well, you could use reflection to access the stack trace - but that's slow, and in some cases I wouldn't be surprised if the JIT skipped some stack frames due to inlining.
One option is to make the methods internal, and only include the "allowed" types within the same assembly. Or make the methods private, and only include the "allowed" types as nested types within the outer type.
There isn't anything more fine-grained than that though - if you need more than the "allowed" types within the assembly, you should think about your trust model... how much control do you have over the other code that ends up in your assembly? If other people you don't trust can change that code, it's game over anyway, and they can undo any protection you add.
If you're trying to prevent accidentally doing the wrong thing, you could use a Roslyn Code Diagnostic, potentially... but fundamentally there's only so far this sort of thing can take you.
See more on this question at Stackoverflow