如何在 VB 代码中调用 C# 扩展方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/213045/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:22:23  来源:igfitidea点击:

How can I call C# extension methods in VB code

c#vb.netextension-methodsclass-library

提问by Greg B

I have a class library with some extension methods written in C# and an old website written in VB.

我有一个类库,其中包含一些用 C# 编写的扩展方法和一个用 VB 编写的旧网站。

I want to call my extension methods from the VB code but they don't appear in intelisense and I get compile errors when I visit the site.

我想从 VB 代码调用我的扩展方法,但它们没有出现在 intelisense 中,并且在我访问该站点时出现编译错误。

I have got all the required Imports because other classes contained in the same namespaces are appearing fine in Intelisense.

我已经获得了所有必需的Import ,因为包含在相同命名空间中的其他类在 Intelisense 中显示良好。

Any suggestions

有什么建议

EDIT:More info to help with some comments.

编辑:更多信息来帮助一些评论。

my implementation looks like this

我的实现看起来像这样

//C# code compiled as DLL
namespace x.y {
    public static class z {
        public static string q (this string s){
             return s + " " + s;
        }

    }
}

and my usage like this

我的用法是这样的

Imports x.y

'...'
Dim r as string = "greg"
Dim s as string = r.q() ' does not show in intelisense
                        ' and throws error : Compiler Error Message: BC30203: Identifier expected.

采纳答案by Jon Skeet

It works for me, although there are a couple of quirks. First, I created a C# class library targeting .NET 3.5. Here's the only code in the project:

它对我有用,尽管有一些怪癖。首先,我创建了一个面向 .NET 3.5 的 C# 类库。这是项目中唯一的代码:

using System;

namespace ExtensionLibrary
{
  public static class Extensions
  {
    public static string CustomExtension(this string text)
    {
      char[] chars = text.ToCharArray();
      Array.Reverse(chars);
      return new string(chars);
    }
  }
}

Then I created a VB console app targeting .NET 3.5, and added a reference to my C# project. I renamed Module1.vb to Test.vb, and here's the code:

然后我创建了一个面向 .NET 3.5 的 VB 控制台应用程序,并添加了对我的 C# 项目的引用。我将 Module1.vb 重命名为 Test.vb,代码如下:

Imports ExtensionLibrary

Module Test

    Sub Main()
        Console.WriteLine("Hello".CustomExtension())
    End Sub

End Module

This compiles and runs. (I would have called the method Reverse() but I wasn't sure whether VB might magically have reverse abilities already somewhere - I'm not a VB expert by a long chalk.)

这将编译并运行。(我本来会调用 Reverse() 方法,但我不确定 VB 是否已经在某处神奇地具有反向功能 - 我不是一个长粉笔的 VB 专家。)

Initially, I wasn't offered ExtensionLibrary as an import from Intellisense. Even after building, the "Imports ExtensionLibrary" is greyed out, and a lightbulb offers the opportunity to remove the supposedly redundant import. (Doing so breaks the project.) It's possible that this is ReSharper rather than Visual Studio, mind you.

最初,我没有提供 ExtensionLibrary 作为从 Intellisense 的导入。即使在构建之后,“Imports ExtensionLibrary”也是灰色的,灯泡提供了删除所谓的冗余导入的机会。(这样做会破坏项目。)请注意,这可能是 ReSharper 而不是 Visual Studio。

So to cut a long story short, it can be done, and it should work just fine. I don't suppose the problem is that you're either using an old version of VB or your project isn't targeting .NET 3.5?

因此,长话短说,它可以完成,而且应该可以正常工作。我不认为问题是您使用的是旧版本的 VB 还是您的项目不是针对 .NET 3.5?

As noted in comments: there's one additional quirk, which is that extension methods won't be found when the compile-time type of the target is Object.

如评论中所述:还有一个额外的怪癖,即当目标的编译时类型为Object.

回答by ICR

Extension methods are just syntactic sugar for static methods. So

扩展方法只是静态方法的语法糖。所以

public static string MyExtMethod(this string s)

can be called in both VB.NET and C# with

可以在 VB.NET 和 C# 中调用

MyExtMethod("myArgument")

回答by Jason Hymanson

I don't know if you can call them in the same dot notation as you would in C#, but I would think that the static extension methods would show up as static functions with the fist argument as the extended type. So you should be able to call the actually class in VB with:

我不知道您是否可以使用与 C# 中相同的点表示法来调用它们,但我认为静态扩展方法将显示为静态函数,并将 fist 参数作为扩展类型。所以你应该能够在 VB 中调用实际的类:

StaticClass.ExtensionMethod(theString, arg1, ..., argN)

Where in C# you would have just written:

在 C# 中,你会在哪里写:

theString.ExtensionMethod(arg1, ..., argN);

With StaticClass being the name of the static class in which you defined your extension methods.

StaticClass 是您在其中定义扩展方法的静态类的名称。

回答by Konrad Rudolph

… and an old website written in VB.

……还有一个用 VB 编写的旧网站。

Does “old” here imply perhaps that you also use an old version of VB here? Anyway, since extension methods are just vanilla static (“Shared”) methods decorated with an attribute, you shouldbe able to call them in any case.

这里的“旧”是否意味着您在这里也使用旧版本的 VB?无论如何,由于扩展方法只是Shared用属性修饰的普通静态(“ ”)方法,因此您应该能够在任何情况下调用它们。

If this isn't possible you either try to call them “extension style” in an old version of VB or you're referencing the wrong version of your C# assembly.

如果这是不可能的,您要么尝试在旧版本的 VB 中将它们称为“扩展样式”,要么引用了错误版本的 C# 程序集。

Edit: are you sure you're Importing the wholenamespace, i.e. x.yand not just x? VB is able to access nested namespaces easier than C# so you can use classes from namespace x.yusing the following code in VB. However, for extension methods to work, the fullpath has to be Imported.

编辑:您确定您正在Import使用整个命名空间,即x.y而不仅仅是x?VB 能够比 C# 更容易访问嵌套命名空间,因此您可以x.y在 VB 中使用以下代码使用命名空间中的类。但是,要使扩展方法起作用,必须编辑完整路径Import

Imports x
Dim x As New y.SomeClass()

回答by k?e?m?p? ?

Imports x.y

'...'
Dim r As String = "greg"
Dim s As String = r.q() 'same as z.q(r) 

回答by Konrad Rudolph

OK. Based on the error message you are definitely notusing the most recent VB version (VB 9!) or the error isn't related to this problem at all because then you'd get another error if the method wasn't found:

好的。根据错误消息,您肯定没有使用最新的 VB 版本(VB 9!),或者该错误根本与此问题无关,因为如果找不到该方法,您将收到另一个错误:

Error 1 'q' is not a member of 'String'.

错误 1 ​​'q' 不是 'String' 的成员。

回答by k?e?m?p? ?

Two things to check:

要检查的两件事:

  1. You're Targeting .Net 3.5
  2. You're referencing the DLL
  1. 您的目标是 .Net 3.5
  2. 您正在引用 DLL

Some tools might incorrectly suggest extension methods for projects that don't support them.

某些工具可能会错误地为不支持它们的项目建议扩展方法。

回答by Greg B

This was quite a while ago and I can't really how I solved it, but needless to say, it was user error. I probably restarted my computer and away it went.

这是很久以前的事了,我真的不知道我是如何解决它的,但不用说,这是用户错误。我可能重新启动了我的电脑,然后它就走了。

回答by NagyBandi

I ran into the same problem, and might accidentally have stumbled upon the solution. If I used

我遇到了同样的问题,可能不小心偶然发现了解决方案。如果我用

x.y.r.q()

, it threw the same error for me as well. But if I imported x.y, it worked, so:

,它也为我抛出了同样的错误。但是如果我导入了 xy,它就起作用了,所以:

using x.y;
...
r.q()

was fine.

很好。

So apparently you have to import it in the declaration to make it work.

所以显然你必须在声明中导入它才能使其工作。

回答by Keith

I think I've encountered a similar problem: VB.Net is quite happy to compile on through extension methods and leave them to be inferred at run-time if Option Strictis off.

我想我遇到了类似的问题:VB.Net 很乐意通过扩展方法进行编译,如果Option Strict关闭,则在运行时对其进行推断。

However, VB.Net really doesn't seem to like extension methods on basic types. You can't extend Objectand it can't resolve it if you do:

然而,VB.Net 似乎真的不喜欢基本类型的扩展方法。Object如果您这样做,您将无法扩展并且无法解决它:

C#

C#

namespace NS
...

public static class Utility {

    public static void Something(this object input) { ...

    public static void Something(this string input) { ...

}

// Works fine, resolves to 2nd method
"test".Something();

// At compile time C# converts the above to:
Utility.Something("test");

However this goes wrong in VB.Net:

然而这在 VB.Net 中出错了:

Option Infer On
Option Explicit On
Option Strict Off
Imports NS
...

    Dim r as String = "test" 
    r.Something()

That compiles without error, but at run time fails because Somethingis not a method of String- the compiler has failed to replace the syntactic sugar of the extension method with the the static call to Utility.Something.

编译没有错误,但在运行时失败,因为Something不是一个方法String- 编译器未能用静态调用替换扩展方法的语法糖Utility.Something

The question is why? Well unlike C#, VB.Net can't handle any extension to Object! The valid extension method in C# confuses the VB.Net compiler.

问题是为什么?与 C# 不同的是,VB.Net 无法处理任何扩展到Object! C# 中的有效扩展方法混淆了 VB.Net 编译器。

As a general VB.Net rule, I'd avoid using extension methods with any of the basic .Net types (Object, String, Integer, etc). You also have to be careful with Option Inferas while it's on by default in Visual Studio it's off by default for command line compiles, VBCodeProvider, and possibly in web sites (depending on your web.config). When it's off everything in VB.Net is considered to be an Objectand all extension methods will be left until run time (and will therefore fail).

作为一般规则,VB.Net,我会避免使用扩展方法与任何基本.NET类型的(ObjectStringInteger等)。您还必须小心,Option Infer因为它在 Visual Studio 中默认为打开状态,它在命令行编译时默认关闭VBCodeProvider,并且可能在网站中(取决于您的 web.config)。当它关闭时,VB.Net 中的所有内容都被认为是 anObject并且所有扩展方法都将保留到运行时(因此会失败)。

I think Microsoft really dropped the ball when they added extension methods to VB.Net, I think it was an afterthought to try (and fail) to make it consistent with C#.

我认为微软在向 VB.Net 添加扩展方法时确实失败了,我认为尝试(但失败)使其与 C# 保持一致是事后的想法。