The telling part is the exception:
{"'object' does not contain a definition for 'Name'"}.
This indicates that the runtime binder was not actually capable of accessing the type you're passing in dynamic
(since dynamic
does actually enforce visibility rules).
The most likely cause of this is that you're creating the anonymous type in a different assembly from the one where you're subsequently reading it - since anonymous types are declared internal
, the consuming assembly cannot access it, causing the error message above.
Contrast with the usual case of runtime binder exceptions:
'<>f__AnonymousType0< string >' does not contain a definition for 'Name'
EDIT:
A possible solution to the problem is to use the InternalsVisibleToAttribute
on the assembly containing the anonymous type. However, this is code smell - just like any other use of InternalsVisibleToAttribute
or internal
itself.
A better way would be to make sure you don't actually pass anonymous types over assembly boundaries - after all, they shouldn't even be used outside of the method they originated from; the fact that they are is basically an implementation detail of .NET - they didn't have another way to do the same thing. This could change in future versions, making the InternalsVisibleToAttribute
solution doubly unreliable.
The way your code is using dynamic
suggests that your team has flawed assumptions about how dynamic
works and how it's supposed to be used. Note how the actual runtime type of List<dynamic>
is actually List<object>
. The same goes for arguments of type dynamic
(which are again just object
, albeit marked with DynamicAttribute
). And in fact, that really is what dynamic
is - it's a way to handle runtime dynamic dispatch - it's not a property of the type or anything, it's just the way you actually invoke whatever you're trying to invoke. For C#, dynamic
allows you to skip most of the compiler checks when working with those dynamic types, and it generates some code to handle the dispatch for you automatically, but all of that only happens inside the method where you actually use the dynamic
keyword - if you used List<object>
, the end result would be exactly the same.
In your code, there's no reason not to use simple static types. Dynamic typing doesn't really give you any benefits, apart from the effort to code the types themselves. If your co-workers don't like that, well, they should present a better solution - the problem is quite obvious, and it's something you need to deal with.
Much worse, it explicitly hides all context, all the type information. That's not something you want in an API, internal or not! If you want to hide the concrete types being used, why not - but you should still expose an interface instead. I suspect this is the reason why anonymous types can't implement interfaces - it would encourage you to go entirely the wrong way.
RuntimeBinderException
? It's likely to be something along the lines of '[Some type]' does not contain a definition for '[Some property]' – Homesicksection.Fields
dynamic/anonymous, or are they static types of varying types? – Cleanthesnew { Name = ... , Id = ... , etc }
. As with regards to the article you mention and the anonymous types issue, everything is taking place in the same assembly, so I assume this should not be the problem. – ShadeList<dynamic>
iterated over and read), but it works fine for me. If I make sure the types don't match, it will only fail on the ones that don't match. I guess you'll have to find the smallest possible full code that reproduces the behaviour you're seeing :) Also, what's your .NET FW version? That said, I don't think this is a proper use case fordynamic
, so perhaps you're going to refactor it anyway? :D – Zendejas{"'object' does not contain a definition for 'Name'"}
is weird. Normally, it would say sth along lines{"'<>f_AnonymousType0<int, int>' does not contain a definition for 'Name'"}
– Haglerinternal
, so I can see how that would cause it to be "dynamicced" intoobject
. – Zendejas'object'
. Is the anonymous type created inside a type that isprivate
, perhaps? One way or another, it must be inaccessible to the runtime binder. – Zendejas