简体   繁体   English

将动态 object 传递给 .NET 6 中的自定义插值字符串处理程序时出现无效的实例化异常

[英]Invalid instantiation exception when pass dynamic object to custom interpolated string handler in .NET 6

I found an issue upgrading to the .NET 6 LogErrorInterpolatedStringHandler in my logger method.我在我的记录器方法中发现了升级到 .NET 6 LogErrorInterpolatedStringHandler的问题。

Here is the classic method:这是经典的方法:

public static void Log(string message, params object[] pars)
{
    // Log message
}

and here is the upgraded one:这是升级后的:

public static void Log(ref LogErrorInterpolatedStringHandler message, params object[] pars)
{
    // Log message
}

I upgraded the method in order to get the performance improvements of C# 10 and .NET 6 described here .我升级了该方法以获得此处描述的 C# 10 和 .NET 6 的性能改进。

The new version of the method works well except when passing dynamic object in the interpolated string.该方法的新版本运行良好,除了在插值字符串中传递dynamic object 时。

Here is an example:这是一个例子:

// Works well   
Logger.Log($"Log: {stringOrEverythingElseObject}");

// Exception
Logger.Log($"Log: {dynamicObject}");

The exception thrown is抛出的异常是

The generic type '<>A{00000004}`3' was used with an invalid instantiation in assembly 'MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.通用类型“<>A{00000004}`3”在程序集“MyAssembly,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”中与无效实例化一起使用。

I found a pull request similar to my problem but could not understand how to fix in my code.我发现了一个类似于我的问题的拉取请求,但无法理解如何在我的代码中修复。

Do you have any idea?你有什么主意吗? Thanks谢谢

TL;DR TL;博士

There is not much you can do except casting dynamicObject to object at the call site:除了在呼叫站点将dynamicObject转换为object之外,您无能为力:

Logger.Log($"Log: {(object)dynamicObject}");

or removing ref from the handler:或从处理程序中删除ref

[InterpolatedStringHandler]
public struct LogErrorInterpolatedStringHandler

But not sure how it will affect performance (though using dynamic should have much more effect on performance than this, in general you should avoid dynamic in performance sensitive code)但不确定它将如何影响性能(尽管使用dynamic应该比这对性能有更大的影响,通常你应该避免在性能敏感代码中使用dynamic

Attempt to explain试图解释

ref struct s do not work with dynamic very well due to the following limitation :由于以下限制ref struct不能很好地与dynamic一起使用:

  • A ref struct can't be a type argument. ref结构不能是类型参数。

While code handling the dynamic uses the related types as type parameters.而处理dynamic的代码使用相关类型作为类型参数。 Ie the following code:即以下代码:

var handler = new Handler();
handler.AppendFormatted((dynamic)5);

ref struct Handler
{
    // or public void AppendFormatted<T>(T value) { }
    public void AppendFormatted(object value) { }
}

Will result in something like this generated by compiler :将导致编译器生成类似这样的内容:

private static class <>o__0
{
    public static CallSite<<>A{00000002}<CallSite, Handler, object>> <>p__0;
}

Note the Handler in the list of type parameters which will lead to the exactly the same runtime error.请注意类型参数列表中的Handler ,这将导致完全相同的运行时错误。 Removing ref from the handler fixes the issue.从处理程序中删除ref可以解决此问题。

As noted in comments in this test and this comment by Stephen Toub currently Roslyn does not emit any build time errors for this code while it fails in runtime.正如本测试中的评论和Stephen Toub的评论中所指出的,目前 Roslyn 在运行时失败时不会为此代码发出任何构建时错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM