Caller member
Granted, getting the caller member name is not "natural" in the object model.
That's why the C# engineers introduced CallerMemberName in the compiler.
The real enemy is duplication, and stack-based workarounds are inefficient.
[CallerMemberName]
allows to get the information without duplication and without ill-effect.
Caller type
But getting the caller member type is natural and easy to get without duplication.
How to do it
Add a "caller" parameter to fooMethod
, no special attribute needed.
public bool fooMethod(object caller, [CallerMemberName]string membername = "")
{
Type callerType = caller.GetType();
//This returns a value depending of type and method
return true;
}
And call it like this:
fooMethod(this);
This answer the question
You stated
// Here I want to get CustClass, not fooBase
and that's exactly what you'll get.
Other situations where it would not work, with solutions.
While this exactly answers your requirements, there are other, different, cases where it wouldn't work.
- Case 1: When caller is a static methods (there is no "this").
- Case 2: When one wants the type of the caller method itself, and not the type of the caller itself (which may be a subclass of the first).
In those cases, a [CallerMemberType]
might make sense, but there are simpler solutions.
Notice that the static caller case is simpler: there is no object so no discrepancy between it and the type of the calling method. No fooBase
, only CustClass
.
Case 1: When caller is a static methods (there is no "this")
If at least one caller is a static method, then don't do the GetType()
inside the method but on call site, so don't pass "this" to the method but the type:
public bool fooMethodForStaticCaller(Type callerType, [CallerMemberName]string membername = "")
Static caller will do:
public class MyClassWithAStaticMethod // can be CustClass, too
{
public static string method1static()
{
fooMethodForStaticCaller(typeof(MyClassWithAStaticMethod));
}
}
To keep compatibility with object callers, either keep the other fooMethod
that takes the this
pointer, or you can remove it and object callers will do:
fooMethod(this.GetType());
You can notice that the typeof(MyClassWithAStaticMethod)
above repeats the class name and it's true. It would be nicer to not repeat the class name, but it's not such a big deal because this repeats only once, as a typed item (not a string) and inside the same class. It's not as serious a problem as the original problem that the [CallerMemberName]
solves, which was a problem of repeating the caller name in all call sites.
Case 2: When one wants the type of the caller method, not the type of the caller
For example, in class fooBase
you want to call anotherFooMethod
from object context but want the type being passed to always be fooBase
, not the actual type of the object (e.g. CustClass
).
In this case there is a this
pointer but you don't want to use it. So, just use actually the same solution:
public class fooBase
{
[CustomAttribute()]
public string method1()
{
if (anotherFooMethod(typeof(fooBase)))
{
....
}
}
}
Just like in case 1, there is one repetition, not one per call site, unless you have an pre-existing problem of rampant code duplication, in which case the problem being addressed here is not the one you should worry about.
Conclusion
[CallerMemberType]
might still make sense to avoid duplication at all, but:
- anything added to the compiler is a complexity burden with maintenance cost
- given the existing solutions I'm not surprised there are items with higher priority in the C# development team list.