Как я могу вызвать методы расширения C # в коде VB - PullRequest
10 голосов
/ 17 октября 2008

У меня есть библиотека классов с некоторыми методами расширения, написанными на C #, и старый сайт, написанный на VB.

Я хочу вызывать методы расширения из кода VB, но они не отображаются в intelisense, и я получаю ошибки компиляции при посещении сайта.

У меня есть все необходимые Импорт с, потому что другие классы, содержащиеся в тех же пространствах имен, прекрасно отображаются в Intelisense.

Любые предложения

РЕДАКТИРОВАТЬ: Дополнительная информация, чтобы помочь с некоторыми комментариями.

моя реализация выглядит так

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

    }
}

и мое использование как это

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.

Ответы [ 10 ]

8 голосов
/ 17 октября 2008

У меня это работает, хотя есть несколько причуд. Сначала я создал библиотеку классов C # для .NET 3.5. Вот единственный код в проекте:

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);
    }
  }
}

Затем я создал консольное приложение VB для .NET 3.5 и добавил ссылку на мой проект на C #. Я переименовал Module1.vb в Test.vb, и вот код:

Imports ExtensionLibrary

Module Test

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

End Module

Это компилируется и запускается. (Я бы назвал метод Reverse (), но я не был уверен, может ли VB магически иметь обратные способности уже где-то - я не эксперт по VB по длинному мелу.)

Изначально мне не предлагали ExtensionLibrary для импорта из Intellisense. Даже после сборки «Imports ExtensionLibrary» отображается серым цветом, а лампочка дает возможность удалить предположительно избыточный импорт. (Это нарушает проект.) Возможно, это ReSharper, а не Visual Studio.

Короче говоря, это можно сделать, и это должно работать просто отлично. Я не думаю, что проблема в том, что вы либо используете старую версию VB, либо ваш проект не нацелен на .NET 3.5?

Как отмечено в комментариях: есть еще одна особенность, которая заключается в том, что методы расширения не будут найдены, когда тип времени компиляции для цели Object.

2 голосов
/ 17 октября 2008

OK. Основываясь на сообщении об ошибке, вы определенно не используете самую последнюю версию VB (VB 9!), Или ошибка вообще не связана с этой проблемой, потому что тогда вы получите другую ошибку, если метод был не найдено:

Ошибка 1 'q' не является членом 'String'.

2 голосов
/ 17 октября 2008

Методы расширения являются просто синтаксическим сахаром для статических методов. Так

public static string MyExtMethod(this string s)

может вызываться как в VB.NET, так и в C # с помощью

MyExtMethod("myArgument")
1 голос
/ 31 августа 2012

Я думаю, что столкнулся с подобной проблемой : VB.Net весьма рад компилировать с помощью методов расширения и оставить их для вывода во время выполнения, если Option Strict выключено.

Однако VB.Net действительно не любит методы расширения для базовых типов. Вы не можете продлить Object, и он не может разрешить его, если вы выполните:

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");

Однако это не так в VB.Net:

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

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

Это компилируется без ошибок, но во время выполнения происходит сбой, поскольку Something не является методом String - компилятору не удалось заменить синтаксический сахар метода расширения статическим вызовом Utility.Something.

Вопрос в том, почему? Ну, в отличие от C #, VB.Net не может обработать любое расширение Object! Допустимый метод расширения в C # сбивает с толку компилятор VB.Net.

Как общее правило VB.Net, я бы избегал использования методов расширения с любым из базовых типов .Net (Object, String, Integer и т. Д.). Вы также должны быть осторожны с Option Infer, так как пока он включен по умолчанию в Visual Studio, он по умолчанию отключен для компиляций командной строки, VBCodeProvider и, возможно, на веб-сайтах (в зависимости от вашего web.config). Когда он выключен, все в VB.Net считается Object, и все методы расширения будут оставлены до времени выполнения (и, следовательно, не будут работать).

Я думаю, что Microsoft действительно отказалась, когда они добавили методы расширения в VB.Net, я думаю, что это было запоздалой попыткой (и неуспешной) привести ее в соответствие с C #.

1 голос
/ 17 октября 2008
Imports x.y

'...'
Dim r As String = "greg"
Dim s As String = r.q() 'same as z.q(r) 
0 голосов
/ 18 сентября 2010

Я столкнулся с той же проблемой и мог случайно наткнуться на решение. Если бы я использовал

x.y.r.q()

, он также выдал ту же ошибку для меня. Но если я импортировал x.y, это сработало, так что:

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

было хорошо.

Так что, очевидно, вы должны импортировать его в декларации, чтобы оно заработало.

0 голосов
/ 07 февраля 2009

Это было довольно давно, и я не могу понять, как я это решил, но, разумеется, это была ошибка пользователя. Я, вероятно, перезагрузил свой компьютер, и он ушел.

0 голосов
/ 17 октября 2008

Две вещи для проверки:

  1. Вы нацеливаетесь на .Net 3.5
  2. Вы ссылаетесь на DLL

Некоторые инструменты могут некорректно предлагать методы расширения для проектов, которые их не поддерживают.

0 голосов
/ 17 октября 2008

… и старый сайт, написанный на VB.

Означает ли "старый" здесь, возможно, что вы также используете старую версию VB здесь? В любом случае, поскольку методы расширения - это просто ванильные статические («Shared») методы, украшенные атрибутом, вы должны иметь возможность вызывать их в любом случае.

Если это невозможно, вы либо пытаетесь назвать их «стилем расширения» в старой версии VB, либо ссылаетесь на неправильную версию вашей сборки C #.

Редактировать: вы уверены, что Import используете целое пространство имен, т.е. x.y, а не просто x? VB может получить доступ к вложенным пространствам имен проще, чем C #, поэтому вы можете использовать классы из пространства имен x.y, используя следующий код в VB. Однако, чтобы методы расширения работали, путь full должен быть Import ed.

Imports x
Dim x As New y.SomeClass()
0 голосов
/ 17 октября 2008

Я не знаю, можете ли вы вызывать их в той же точечной записи, как в C #, но я думаю, что методы статического расширения будут отображаться как статические функции с аргументом fist в качестве расширенного типа. Таким образом, вы должны иметь возможность вызывать фактически класс в VB с помощью:

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

Где в C # вы бы просто написали:

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

С StaticClass, являющимся именем статического класса, в котором вы определили ваши методы расширения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...