Pergunta

Eu tenho uma biblioteca de classe com alguns métodos de extensão escritos em C # e um Web site velho escrito em VB.

Eu quero chamar meus métodos de extensão a partir do código VB, mas eles não aparecem no Intelisense e eu recebo erros de compilação quando eu visitar o site.

Eu tenho todo o necessário Importar é porque outras classes contidas nos mesmos namespaces estão aparecendo bem em Intelisense.

Todas as sugestões

EDIT:. Mais informações para ajudar com alguns comentários

minha implementação olhares como este

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

    }
}

e meu uso como esta

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.
Foi útil?

Solução

Ele funciona para mim, embora há um par de peculiaridades. Primeiro, eu criei uma biblioteca de classes C # direcionamento .NET 3.5. Aqui é o único código no projeto:

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

Então eu criei um console app VB alvo o .NET 3.5, e acrescentou uma referência ao meu projeto C #. I renomeado Module1.vb para Test.vb, e aqui está o código:

Imports ExtensionLibrary

Module Test

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

End Module

Este compila e é executado. (Eu teria chamado o método reverso (), mas eu não tinha certeza se VB pode magicamente têm habilidades reversa já em algum lugar -. Eu não sou um especialista em VB por um longo giz)

Inicialmente, eu não estava oferecido ExtensionLibrary como uma importação de Intellisense. Mesmo depois de edifício, o "Importações ExtensionLibrary" é acinzentado, e uma lâmpada oferece a oportunidade para remover a importação supostamente redundante. (Se o fizer, quebra o projeto.) É possível que este é ReSharper em vez de Visual Studio, você mente.

Assim, para cortar uma longa história curta, que pode ser feito, e deve funcionar muito bem. Não creio que o problema é que ou você está usando uma versão antiga do VB ou seu projeto não tem como alvo o .NET 3.5?

Como observado nos comentários: há uma peculiaridade adicional, o que é que os métodos de extensão não será encontrado quando o tipo em tempo de compilação do alvo é Object .

Outras dicas

Os métodos de extensão são apenas açúcar sintático para métodos estáticos. Então

public static string MyExtMethod(this string s)

pode ser chamado tanto em VB.NET e C # com

MyExtMethod("myArgument")

OK. Com base na mensagem de erro você está definitivamente não usando a versão mais recente VB (VB 9!) Ou o erro não está relacionado a este problema em todos, porque então você teria outra erro se o método não foi encontrada:

Erro 1 'q' não é um membro de 'String'.

Imports x.y

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

Eu acho que encontrou um problema semelhante: VB.Net é muito feliz para compilar on através de métodos de extensão e deixá-los para se inferir em tempo de execução se Option Strict está desligado.

No entanto, VB.Net realmente não parece como métodos de extensão sobre tipos básicos. Não é possível estender Object e não pode resolvê-lo se você fizer isso:

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

No entanto, este dá errado em VB.Net:

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

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

que compila sem erro, mas em tempo de execução falha porque Something não é um método de String -. O compilador não conseguiu substituir o açúcar sintático do método de extensão com a chamada do estático para Utility.Something

A questão é por quê? Bem ao contrário de C #, VB.Net não pode lidar com qualquer extensão para Object ! O método de extensão válida em C # confunde o VB.Net compilador.

Como regra geral VB.Net, eu evitar o uso de métodos de extensão com qualquer um dos tipos Basic .Net (Object, String, Integer, etc). Você também tem que ter cuidado com Option Infer como enquanto é ativado por padrão no Visual Studio é desligado por padrão para compilações de linha de comando, VBCodeProvider e, possivelmente, em web sites (dependendo do seu web.config). Quando ele está fora tudo em VB.Net é considerado um Object e todos os métodos de extensão será deixado até tempo de execução (e, portanto, falhar).

Eu acho que a Microsoft realmente deixou a bola cair quando adicionado métodos de extensão para VB.Net, eu acho que foi uma reflexão tardia para tentar (e falhar) para torná-lo compatível com C #.

Eu não sei se você pode chamá-los na mesma notação de ponto como você faria em C #, mas eu acho que os métodos de extensão estáticos iria aparecer como funções estáticas com o argumento de punho como o tipo prolongado. Então você deve ser capaz de chamar o realmente classe em VB com:

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

Onde em C # você acabou de escrever:

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

Com StaticClass sendo o nome da classe estática em que você definiu seus métodos de extensão.

... e um antigo site escrito em VB.

O “velho” aqui implica, talvez, que também utiliza uma versão antiga do VB aqui? De qualquer forma, uma vez que os métodos de extensão são ( “Shared”) métodos estáticos apenas baunilha decorada com um atributo, você deve ser capaz de chamá-los em qualquer caso.

Se isto não for possível, você quer tentar chamá-los de “estilo extensão” em uma versão antiga do VB ou você está fazendo referência a versão errada do seu C # montagem.

Editar: Tem certeza de que você está Importing o toda namespace, ou seja x.y e não apenas x? VB é capaz de acessar aninhadas namespaces mais fácil do que C # para que você pode usar classes de x.y namespace usando o seguinte código no VB. No entanto, para os métodos de extensão para o trabalho, a completo caminho tem de ser Imported.

Imports x
Dim x As New y.SomeClass()

Duas coisas para verificar:

  1. Você está alvejando Net 3.5
  2. Você está referenciando a DLL

Algumas ferramentas podem sugerir incorretamente métodos de extensão para projetos que não apoiá-los.

Eu corri para o mesmo problema, e pode acidentalmente ter tropeçado em cima da solução. Se eu usei

x.y.r.q()

, ele jogou o mesmo erro para mim também. Mas se eu importados X.Y, funcionou, assim:

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

estava bem.

Então, aparentemente você tem que importá-lo na declaração para torná-lo trabalho.

Este foi um bom tempo atrás, e eu realmente não posso como eu resolver isso, mas escusado será dizer que foi erro do usuário. Eu provavelmente reiniciado meu computador e longe foi.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top