[英]Invalid instantiation exception when pass dynamic object to custom interpolated string handler in .NET 6
我在我的记录器方法中发现了升级到 .NET 6 LogErrorInterpolatedStringHandler
的问题。
这是经典的方法:
public static void Log(string message, params object[] pars)
{
// Log message
}
这是升级后的:
public static void Log(ref LogErrorInterpolatedStringHandler message, params object[] pars)
{
// Log message
}
我升级了该方法以获得此处描述的 C# 10 和 .NET 6 的性能改进。
该方法的新版本运行良好,除了在插值字符串中传递dynamic
object 时。
这是一个例子:
// Works well
Logger.Log($"Log: {stringOrEverythingElseObject}");
// Exception
Logger.Log($"Log: {dynamicObject}");
抛出的异常是
通用类型“<>A{00000004}`3”在程序集“MyAssembly,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”中与无效实例化一起使用。
我发现了一个类似于我的问题的拉取请求,但无法理解如何在我的代码中修复。
你有什么主意吗? 谢谢
TL;博士
除了在呼叫站点将dynamicObject
转换为object
之外,您无能为力:
Logger.Log($"Log: {(object)dynamicObject}");
或从处理程序中删除ref
:
[InterpolatedStringHandler]
public struct LogErrorInterpolatedStringHandler
但不确定它将如何影响性能(尽管使用dynamic
应该比这对性能有更大的影响,通常你应该避免在性能敏感代码中使用dynamic
)
试图解释
由于以下限制, ref struct
不能很好地与dynamic
一起使用:
ref
结构不能是类型参数。
而处理dynamic
的代码使用相关类型作为类型参数。 即以下代码:
var handler = new Handler();
handler.AppendFormatted((dynamic)5);
ref struct Handler
{
// or public void AppendFormatted<T>(T value) { }
public void AppendFormatted(object value) { }
}
将导致编译器生成类似这样的内容:
private static class <>o__0
{
public static CallSite<<>A{00000002}<CallSite, Handler, object>> <>p__0;
}
请注意类型参数列表中的Handler
,这将导致完全相同的运行时错误。 从处理程序中删除ref
可以解决此问题。
正如本测试中的评论和Stephen Toub的评论中所指出的,目前 Roslyn 在运行时失败时不会为此代码发出任何构建时错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.