简体   繁体   English

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

[英]VB.NET and calling byval/byref C# overloads

We have a C# class, which includes two functions, whose parameters differ only by the parameter modifier: 我们有一个C#类,其中包括两个函数,它们的参数仅在参数修饰符上有所不同:

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

Now we need to call this method (any of them, actually) from VB.NET. 现在我们需要从VB.NET调用此方法(实际上是其中任何一个)。 The problem is that the VB.NET compiler can't decide, which method to use. 问题在于VB.NET编译器无法决定使用哪种方法。

The question is: is there a way to tell the compiler that we want the first variant (or the second one, it doesn't matter for the caller)? 问题是:有没有办法告诉编译器我们想要第一个变体(或者第二个变体,对调用者来说没有关系)?

Writing the call as DoSomething((myObj)) (ie adding parentheses) in VB.NET doesn't help. 在VB.NET中将呼叫编写为DoSomething((myObj)) (即添加括号)无济于事。

You could create a separate library written in C# that provides helper methods with distinct names to enable you to call the ambiguously defined DoSomething methods. 您可以创建一个单独的用C#编写的库,该库为助手方法提供不同的名称,以使您能够调用模棱两可定义的DoSomething方法。 You shouldn't have to do that, and people might wonder why you did, so you could fill it with scathing comments explaining why it was necessary. 您不必这样做,并且人们可能会想知道您为什么这样做,因此您可以在其中添加严厉的评论,解释为什么这样做是必要的。

Or you could use reflection, something roughly like this: 或者您可以使用反射,大致像这样:

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, the only way would be to force the call to the API using Reflection. AFAIK,唯一的方法是使用Reflection强制对API的调用。 Although I am not completely sure if that would work. 尽管我不确定是否可以。

The problem is that creating 2 overloads only differing by ref is not CLS compliant and therefore not guaranteed to work in all .NET languages. 问题在于,创建2个仅因ref而不同的重载不符合CLS,因此不能保证在所有.NET语言中都能正常工作。 To prevent getting into this situation, you should add the CLSCompliantAttribute to your AssemblyInfo.cs file and then the compiler will warn you when you have broken CLS compatibility. 为避免发生这种情况,应将CLSCompliantAttribute添加AssemblyInfo.cs文件中,然后当CLS兼容性中断时,编译器将向您发出警告。

[assembly: System.CLSCompliant(true)]

A way you could fix this is by adding a wrapper function that can be called via VB.NET. 解决此问题的一种方法是添加可以通过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);
}

There are a few different ways you could make this cleaner, such as making a separate assembly to wrap it as Scott Hannen mentioned, or simply by making the wrapper method for CLS compliance an extension method. 您可以通过几种不同的方法来使此清洁器更清洁,例如,如Scott Hannen所述,制作一个单独的程序集以对其进行包装,或者只是将符合CLS的wrapper方法用作扩展方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM