That code is fatally flawed.
It does work, as long as you specify that property:
void Bar()
{
Foo(new {Position = 0});
}
void Foo(dynamic args)
{
Console.WriteLine(args.Position);
}
That will output 0
, it will not throw a RuntimeBinderException
.
But the purpose of such code is the possibility for the caller to specify only the properties needed and omit the rest.
You are trying to check for this omission via if(args.Position != null)
. But that doesn't work, it already requires Position
to exist.
When you have a look at the routing API of ASP.NET that also supports those anonymous configuration objects you will notice that the type of the parameter is object
and not dynamic
.
Using object
instead of dynamic
will enable your API to be used across assembly boundaries.
So how does it work?
Just like in the linked answer, you need to manually create a dictionary of the properties. Whether you use a plain old Dictionary<string, object>
or an ExpandoObject
is a matter of preference.
Using ExpandoObject
will make your code a bit simpler to read and write, but it is not required.
About the actual exception you are getting:
Please note that it tells you it can't find the Position
property on object
. If it would be an anonymous type that was missing the Position
property the exception message wouldn't refer to object
but to an anonymous type. Something like this:
'<>f__AnonymousType0'
does not contain a definition for 'Position'