It turns out that there is a way to do it using the [CallerArgumentExpression("value")]
attribute
Here's an example of the code you're saying you need:
void Main()
{
var myObj = new MyObj() { Amount = 42 };
myObj.Amount.DoSomething();
}
public class MyObj
{
public decimal Amount { get; init; }
}
public static class Extensions
{
public static void DoSomething(this decimal value, [CallerArgumentExpression("value")] string caller = "?")
{
Console.WriteLine($"caller: {caller}");
Console.WriteLine($"value: {value}");
}
}
When run this gives:
caller: myObj.Amount
value: 42
You need to parse out the Amount
string.
Unfortunately, this code can easily become difficult to work with and it can be abused.
Look at this extension to MyObj
:
public class MyObj
{
public decimal Amount { get; init; }
public decimal Amount2() => this.Amount;
public decimal Amount3(decimal factor) => this.Amount * factor;
}
Now I can write this code:
var myObj = new MyObj() { Amount = 42 };
myObj.Amount.DoSomething();
myObj.Amount2().DoSomething();
myObj.Amount3(2).DoSomething();
decimal x = 43;
x.DoSomething();
44m.DoSomething();
myObj.Amount3(x).DoSomething();
0m.DoSomething("Ha ha");
That gives me:
caller: myObj.Amount
value: 42
caller: myObj.Amount2()
value: 42
caller: myObj.Amount3(2)
value: 84
caller: x
value: 43
caller: 44m
value: 44
caller: myObj.Amount3(x)
value: 1806
caller: Ha ha
value: 0
You will really need to be prepared to parse the various structures returned and you will need to know when your code is calling the extension method and you'll need to know when nefarious calling code is trying to spoof who it is.