I have a function defined as follow public void FunctionA(params object args[])
and I can call it like this FunctionA(1+2, a+b);
Is there a way for source generator to change the call to FunctionA(1+2, a+b, "1+2", "a+b");
?
Basically, I need to have the input args also as a string before evaluation (similar to CallerArgumentExpression
attribute functionality).
Can a source generator change/update existing code or just add a new code?
You cannot do this with source generators. They cannot modify existing code, only add new code.
Strictly speaking this is possible, in a rather ugly way which is currently in preview (and might yet change / be removed), see Marc's answer or here.
You can get close to what you want with [CallerArgumentExpression]
: this lets you specify an extra parameter which is filled in by the compiler at compile-time:
This means you could write:
void FunctionA(object arg, [CallerArgumentExpression("arg")] string? message = null)
{
}
FunctionA(a + 1);
And the compiler would insert a string for message
at compile-time:
FunctionA(a + 1, "a + 1");
However, this doesn't seem to play well with params
: a params
parameter needs to be the last parameter passed to a function, which means you'd need to do this:
void FunctionA([CallerArgumentExpression("args")] string? message = null, params object[] args)
{
}
... but then you'd have to use named parameters to avoid passing a value for message
, and you can't use named parameters with params
(sensibly), so that doesn't work.
You could remove params
, and do:
void FunctionA(object[] args, [CallerArgumentExpression("args")] string? message = null)
{
}
FunctionA([a + 1, a + 2]);
... but then you only have a single message
for the whole of args
. The compiler inserts the following at compile time:
FunctionA([a + 1, a + 2], "[a + 1, a + 2]");
... which probably isn't what you want.
If you don't mind having multiple overloads for different numbers of parameters, you can do e.g.:
void FunctionA(
object arg1,
object arg2,
[CallerArgumentExpression("arg1")] string? message1 = null,
[CallerArgumentExpression("arg2")] string? message2 = null)
{
}