Como posso chamar C métodos # extensão em código VB
-
03-07-2019 - |
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 ??p>
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.
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á Import
ing 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 Import
ed.
Imports x
Dim x As New y.SomeClass()
Duas coisas para verificar:
- Você está alvejando Net 3.5
- 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.