gpt4 book ai didi

c# - 在 C# 中使用动态绑定(bind)代替严格类型值的扩展方法

转载 作者:行者123 更新时间:2023-12-04 00:53:52 25 4
gpt4 key购买 nike

我有一个返回 int 值的短表达式,我正在尝试对结果值调用扩展方法,但是当内部表达式中存在任何动态变量时,将使用动态联编程序并且我收到异常Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 消息为

'int' does not contain a definition for 'AsStringOrNull'

以下是重现该问题的所有代码:

using System;

namespace ExtensionMethodsAndDynamic
{

static class Extensions
{
public static string AsStringOrNull(this object value) => value?.ToString();
}

class Program
{
public static object Foo(object value) => value;
static int GetIntFrom(object anything) => 1;


static void Main()
{
dynamic dynamicVariable = null;

string result1 = GetIntFrom((object)dynamicVariable).AsStringOrNull();// Works as expected
string result2 = GetIntFrom(dynamicVariable).AsStringOrNull();
string result3 = GetIntFrom(Foo(dynamicVariable)).AsStringOrNull();
}
}
}

另外,我注意到另一个我无法理解的行为。
The function is successfully called with a strictly typed argument
The same doesn't work for a dynamic argument
But it will work if we specify the function

请帮助我理解为什么与动态变量相关的内容会传播到此函数 int GetIntFrom(object anything) 的调用之外。

最佳答案

扩展方法在编译时进行评估,并替换为适当的静态调用。但是当您使用 dynamic 时,调用会在运行时解析。这意味着当您在动态变量后键入“AsStringOrNull”时,您所做的事情与在静态类型变量后键入它时完全不同。

编译器完成工作后,实际执行的代码有点像这样:

static class Extensions
{
// Note the absent "this" keyword. It's just an ordinary method after compilation
public static string AsStringOrNull(object value) => value?.ToString();
}

class Program
{
public static object Foo(object value) => value;
static int GetIntFrom(object anything) => 1;


static void Main()
{
dynamic dynamicVariable = null;

string result1 = Extensions.AsStringOrNull(GetIntFrom((object)dynamicVariable));

object intObj = GetIntFrom(dynamicVariable); // this step is actually much more complicated
string result2 = intObj.GetType().GetMethod("AsStringOrNull")?.Invoke(intObj) ?? throw new RuntimeBinderException();
}
}

为了简洁起见,我不会列出 result3 会发生什么。上面应该已经说清楚了为什么会抛出异常。当方法解析中涉及任何动态变量时,您就不能使用静态编译器糖。

IDE 不会在这里生成任何错误,因为动态对象出于显而易见的原因根本不检查错误。但是,如果您尝试在第二次和第三次调用“AsStringOrNull”时使用 Go To Reference/F12,您应该会看到它们没有被解析。

关于c# - 在 C# 中使用动态绑定(bind)代替严格类型值的扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64292891/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com