我想使用这样的方法调用来格式化任何数字类型:
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 On、Dynamic Keyword equivalent in VB.Net?),我认为当传递数字类型( double 、十进制、整数等)时,此代码将起作用。它没有,正如您在屏幕截图中看到的那样:
我可以将参数显式转换为 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;
}
}
那么给了什么? 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/