Building with .NET Native tool chain causes error

2019-07-08 05:42发布

问题:

I have a piece of code that gets a JSON response and checks whether there is a .error field

dynamic jsonResponse = JsonConvert.DeserializeObject(responseString);
if (jsonResponse.error != null) { error = jsonResponse.error; }
else
{
  success = true;
}

This runs successfully when it is not compiled with .NET Native toolchain but produces an error (on jsonResponse.error) when it's built with it.

What is the reason for this? Any other similar incompatible behavior with native code?

EDIT: It turns out that even if there is an "error" key in the JSON, we still get an error. The exception is:

System.Reflection.MissingMetadataException: ''Microsoft.CSharp.RuntimeBinder.CSharpGetMemberBinder' is missing metadata. For more information, please visit http://go.microsoft.com/fwlink/?LinkID=392859'

回答1:

The subsystem that powers the dynamic keyword has various corner cases that don't run super well on .NET Native. This particular issue was reported to us in February, you can see some discussion on the CoreFX GitHub here.

The general idea is that the dynamic keyword causes a great deal of machinery to wander through APIs and some pieces of the framework don't have the proper hinting to say "This isn't a thing you need to reflect on." Because our compiler analysis says you won't need this type at runtime but this particular component does, we end up throwing this exception.

The link in the exception is trying to help build a runtime directive (think of it as a hint to the .NET Native compiler) so that we'll know you'll need type information at runtime. For this particular case it would look like:

<Type Name="Microsoft.CSharp.RuntimeBinder.CSharpGetMemberBinder" Dynamic="Required All"/>

If you add that to the the file Properties\Default.rd.xml I would expect this error to disappear. You may hit additional errors of this type but they should be able to be addressed in a similar fashion.

We've logged a bug on our side to get this addressed at some point in the future but you'll need this workaround in the meantime.