VB.NET 无法区分重载函数

VB.NET unable to differentiate between overloaded functions

当前版本的 MVVM Light 在 ObservableObject class 中有一个名为 Set 的辅助函数,继承 ViewModel class 可以调用它来改变 属性值并在一次调用中引发更改通知。与新的 NameOf 运算符一起,这使得属性的样板代码变得更小。

但是问题是 Set 函数被重载了,在 3 个重载中,以下 2 个重载使 VB.NET 生气:

Protected Function [Set](Of T)(propertyName As String, ByRef field As T, newValue As T) As Boolean
Protected Function [Set](Of T)(ByRef field As T, newValue As T, <CallerMemberName> Optional propertyName As String = Nothing) As Boolean

现在,如果您有一个 String 类型 属性,VB.NET 无法区分我们正在调用哪个重载。

Overload resolution failed because no accessible '[Set]' is most specific for these arguments:

'Protected Overloads Function [Set](Of String)(propertyName As String, ByRef field As String, newValue As String) As Boolean': Not most specific.

'Protected Overloads Function [Set](Of String)(ByRef field As String, newValue As String, [propertyName As String = Nothing]) As Boolean': Not most specific.

请注意,C# 可以通过使用 ref 关键字轻松处理这种情况。此外,即使当前情况与 MVVM Light 有关,问题本身也是普遍的。我也尝试过使用命名参数,但这也无济于事。关于如何解决这个问题的任何提示?

时隔将近一年再次来到这里。我刚刚找到了一个适用于大多数情况的小解决方法。不要调用问题中提到的重载之一,而是使用第三个重载:

Protected Function [Set](Of T)(ByRef field As T, newValue As T, <CallerMemberName> Optional propertyName As String = Nothing) As Boolean

此重载的第三个参数是可选的,如果您在调用中跳过它,它将使用 CallerMemberName 为其赋值。由于 Set 几乎总是从 属性 中调用,因此这种方法应该可以很好地工作。没有其他重载需要两个参数,因此编译器可以正确解析它。