VB.NET 并调用 byval/byref C# 重载

VB.NET and calling byval/byref C# overloads

我们有一个C#class,它包含两个函数,其参数仅参数修饰符不同:

bool DoSomething(Object obj){};
bool DoSomething(ref Object obj){};

现在我们需要从 VB.NET 调用这个方法(实际上是其中任何一个)。问题是 VB.NET 编译器无法决定使用哪种方法。

问题是:有没有办法告诉编译器我们想要第一个变体(或第二个变体,对调用者来说无关紧要)?

在 VB.NET 中将调用写为 DoSomething((myObj))(即添加括号)没有帮助。

AFAIK,唯一的方法是使用反射强制调用 API。虽然我不完全确定这是否有效。

问题是创建 2 个仅相差 ref 的重载不符合 CLS,因此不能保证在所有 .NET 语言中工作。为防止出现这种情况,您应该将 CLSCompliantAttribute 添加到 AssemblyInfo.cs 文件中,然后编译器会在您破坏 CLS 兼容性时向您发出警告。

[assembly: System.CLSCompliant(true)]

解决此问题的一种方法是添加可通过 VB.NET.

调用的包装函数
bool DoSomething(Object obj){};
bool DoSomething(ref Object obj){};

// Call this method from VB.NET
bool DoSomething2(ref Object obj)
{
    return DoSomething(ref obj);
}

有几种不同的方法可以使这个更干净,例如像 Scott Hannen 提到的那样制作一个单独的程序集来包装它,或者简单地通过使符合 CLS 的包装方法成为扩展方法。

您可以创建一个用 C# 编写的单独库,它提供具有不同名称的辅助方法,使您能够调用定义不明确的 DoSomething 方法。你不应该这样做,人们可能想知道你为什么这样做,所以你可以用严厉的评论来解释为什么有必要这样做。

或者你可以使用反射,大致如下:

Dim methods = GetType(WhatEverTheType).GetMethods()
Dim doSomethingMethod = methods.Single(Function(method As MethodInfo)
        Return method.Name = "DoSomething" _
        And Not method.GetParameters()(0).ParameterType.IsByRef
    End Function)
doSomethingMethod.Invoke(instanceOfWhatEverTheType)