gpt4 book ai didi

vb.net - VB中的动态方法调用没有反射

转载 作者:行者123 更新时间:2023-12-04 15:23:38 25 4
gpt4 key购买 nike

我想使用这样的方法调用来格式化任何数字类型:

Option Infer On
Option Strict Off
Imports System.Runtime.CompilerServices

Namespace GPR
Module GPRExtensions
<Extension()>
Public Function ToGPRFormattedString(value) As String
' Use VB's dynamic dispatch to assume that value is numeric
Dim d As Double = CDbl(value)
Dim s = d.ToString("N3")
Dim dynamicValue = value.ToString("N3")
Return dynamicValue
End Function
End Module
End Namespace

现在,根据网络上的各种讨论( VB.Net equivalent for C# 'dynamic' with Option Strict OnDynamic Keyword equivalent in VB.Net?),我认为当传递数字类型( double 、十进制、整数等)时,此代码将起作用。它没有,正如您在屏幕截图中看到的那样:

Exception showing dynamic method call failing

我可以将参数显式转换为 double ,然后 .ToString("N3")有效,但只是在所谓的动态 value 上调用它论证失败。

但是,我可以使用以下代码在 C# 中执行此操作(使用 LINQPad)。 (注意,编译器不允许您在扩展方法中使用 dynamic 参数,所以这可能是问题的一部分。)
void Main()
{
Console.WriteLine (1.ToGPRFormattedString());
}

internal static class GPRExtensions
{
public static string ToGPRFormattedString(this object o)
{
// Use VB's dynamic dispatch to assume that value is numeric
var value = o as dynamic;
double d = Convert.ToDouble(value);
var s = d.ToString("N3").Dump("double tostring");
var dynamicValue = value.ToString("N3");
return dynamicValue;
}
}

Dynamic method invocation in C# works

那么给了什么? VB中有没有一种方法可以在不使用反射的情况下动态调用函数的参数?

最佳答案

明确回答“VB中有没有一种方法可以在不使用反射的情况下对函数的参数动态调用方法?”:
编辑:我现在查看了一些 IL 反汇编(通过 LinqPad)并将其与 CallByName 的代码进行了比较。 (通过反射器)并使用 CallByName使用相同数量的 Reflection像往常一样,Option Strict Off后期绑定(bind)。
所以,完整的答案是:你可以用 Option Strict Off 来做到这一点。为所有 Object引用,除非您尝试的方法存在于 Object本身,您可以在其中使用 CallByName 获得相同的效果(事实上,不需要 Option Strict Off )。

Dim dynamicValue = CallByName(value, "ToString", CallType.Method, "N3")
注意 这实际上并不等同于后期绑定(bind)调用,它必须满足“方法”实际上是一个(n 索引)属性的可能性,因此它实际上调用了以下等价物:
Dim dynamicValue = CallByName(value, "ToString", CallType.Get, "N3")
对于其他方法,例如 Double.CompareTo .

细节
你的问题是 Object.ToString()存在,因此您的代码不尝试任何动态调度,而是在默认 String.Chars 上进行数组索引查找 String 的属性(property)结果 value.ToString()称呼。
您可以通过尝试 value.ToString(1,2) 来确认这是编译时发生的情况。 ,您更愿意尝试运行时查找两个参数 ToString ,但实际上失败了

Too many arguments to 'Public ReadOnly Default Property Chars(index As Integer) As Char'


在编译时。
您可以类似地确认所有其他非 Shared Object使用 callvirt 直接调用方法,依靠 Overrides在可用的情况下,不是通过调用 Microsoft.VisualBasic.CompilerServices.NewLateBinding 进行动态调度命名空间,如果您在 IL 中查看已编译的代码。

关于vb.net - VB中的动态方法调用没有反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17819977/

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