Disadvantages of the current implementation:
- They violate the DRY principle as you have to rewrite the parameters everywhere you need them
- They ruin implementation-hiding as you have to specify those parameters already in the interface - even if only a single one of your interface implementation needs them
- They soil your interface, users see them in auto-complete, documentation, etc. pp.
Why have the language designers decided against something much more useable like:
public void Foo()
{
Console.WriteLine(CallerInformation.File);
}
I guess that this implementation lacks some features: e.g. if Foo() is a class implementing IFoo and IFoo is in another assembly, how should any caller of IFoo know at compile-time that the information is required - he can't know that.
But! Isn't it better to document that this works only within one "build step" instead of producing something unusable as the current implementation?
Q1: Is there official documentation about why it is implemented the way it is now?
Q2: Does anybody know of a better solution in other languages?
Caller information attributes are semantically related to method arguments (Like 'If no value is specified for this string parameter, then put the caller member name in it instead of using null as a default value'), hence I see no reason why they shouldn't be related also syntactically as it currently is.
Other approaches would also need to do something each time it wants to assign the caller member name to a variable, like: param = param ?? SomeExpressionToGetSomeValue
Regarding implementation-hiding: It is the duty of the caller to provide arguments, so this should be in the interface (unless the runtime decides to always provide such info in all calls which would be like implicitly providing arguments - and providing arguments implicitly/magically behind the scenes doesn't seem like a better approach to me)
Regarding having to specify to specify those parameters already in the interface - even if only a single one of your interface implementation needs them: Only specify the attribute and the parameter if it is needed. This is why Math.Abs is declared as public static int Abs(int value) and not as public static int Abs(int value, object ThisIsNotNeededButLetsJustHaveItHereItAnyways)
Hmmmm I can't see why you think that's a bad thing - if the caller should supply its name, it should be in documentation etc.
What you seem to suggest yourself is something like reading stack frames, and this will compile and run but might not do what you expect:
The above code will get the name of the caller at runtime, but it might not be the same as the name of the caller at compile time due to inlining or tail call optimization.
Hence, if the method wants caller information as it is during compile time (not runtime), such an approach wouldn't work.