10

I have a class library with some extension methods written in C# and an old website written in 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.

I have got all the required Imports because other classes contained in the same namespaces are appearing fine in 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.
5
  • Have you added a reference to the c# library in your VB Project? Commented Oct 17, 2008 at 17:33
  • I can't think of any reason why the static method invokation would not work if the rest of the library works. Does it work if you make it a non-extension method (just to try and diagnose what's wrong). Commented Oct 17, 2008 at 17:38
  • One more question - Are you sure that the VB.Net project has been changed to target the .net 3.5 framework? I ask because you mention that it's an old website. Commented Oct 17, 2008 at 18:16
  • @rjrapson from my original post "I have got all the required Imports because other classes contained in the same namespaces are appearing fine in Intelisense." @ICR I will try that. @rajrapson yes, I changed the target in the properties and checked the web.config for all the extra nodes Commented Oct 17, 2008 at 18:32
  • You don't need to target .Net 3.5 for extension methods to work, but you do need to use VS2008. And if you're deploying an uncompiled version of your site the server will need to have .net 3.5 installed, or it won't compile properly. Commented Nov 10, 2008 at 20:50

11 Answers 11

8

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:

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:

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.)

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.

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?

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I think you may be right about it being ReSharper. I don't get it grayed out.
Being as this seems to be the first google result for missing extension methods in VB, and the accepted answer is from the great Skeet; I feel there should be a caveat on here about how they don't work with type 'Object's in VB specifically. Spent a couple of hours going back and forth over this in google results until I came across this SO answer from @jdot.
@ZexksMarquise: Thanks, will add a link.
2

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

MyExtMethod("myArgument")

1 Comment

Thanks, I know what and how Extension methods work. My extensions work fine from other C# project however, as my original question stated, the do not appear and and will not compile in VB project that reference the same DLL's
2

OK. Based on the error message you are definitely not using 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:

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

1 Comment

It was so long ago I can't remember the actual issue
1
Imports x.y

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

Comments

1

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 Strict is off.

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

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:

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 Something is 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.

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.

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 Infer as 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 Object and all extension methods will be left until run time (and will therefore fail).

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#.

3 Comments

Actually, the spot they dropped the ball is when they decided to have Object be the default type in Option Strict Off mode and jinx its behavior to kinda sorta line up with the VB6 Variant, rather than defining a proper Variant type which would be largely synonymous with Object, except that only Variant would have VB6-style behavioral quirks]. Many other problems flow from that.
@supercat quite possibly - they had many more problems with the design of VB.Net because of the need to handle upgraded VB6 projects.
It's really too bad; VB.NET still has some horrible quirky behaviors which stem from that. Perhaps MS should add an "Option Quirks Off" for things which would change inherited quirky run-time behaviors [e.g. Dim Five As Object=5 : Debug.Print("{0}",Object.ReferenceEquals(Five,Five)) prints false!], as well as a few sub-options for "Option Strict" [IMHO myGraphics.DrawLine(mypen,5/2,3/4) should compile (drawing a line to (2.5f,0.75f) but Threading.Interlocked.CompareExchange("Hey", "Wow", "Foo") should not (passing read-only value as ByRef parameter)].
0

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:

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

Where in C# you would have just written:

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

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

Comments

0

… and an old website written in 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 should be able to call them in any case.

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.

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

Imports x
Dim x As New y.SomeClass()

1 Comment

Yes, I'm importing the full namespace, and by "old" I simply mean It's a site that I didn't write and hence, is in VB. A casual "old" rather than an technically "old" site
0

Two things to check:

  1. You're Targeting .Net 3.5
  2. You're referencing the DLL

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

Comments

0

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:

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

was fine.

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

Comments

0

You can do this in VB.Net (Framework 2.0 and above) as well. See an example below:

Imports System.Runtime.CompilerServices

Module StringExtensions
    <Extension()>
    Public Function PrintAndPunctuate(ByVal aString As String, ByVal punc As String) As String
         return aString & punc
    End Function
End Module

This link below may help you more, as it helped me a lot!

https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/procedures/how-to-call-an-extension-method
Original souce - Microsoft Learn

Comments

-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.