我们有一个 C# 类,它包含两个函数,其参数仅因参数修饰符而异:
bool DoSomething(Object obj){};
bool DoSomething(ref Object obj){};
现在我们需要从 VB.NET 调用此方法(实际上是其中任何一个(。问题是 VB.NET 编译器无法决定使用哪种方法。
问题是:有没有办法告诉编译器我们想要第一个变体(或第二个变体,对调用者来说无关紧要(?
将调用编写为DoSomething((myObj))
(即添加括号(VB.NET 无济于事。
可以创建一个用 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)
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 合规性的包装方法作为扩展方法。