una - ¿Cómo puedo llamar a los métodos de extensión C#en el código VB?
llamar un metodo en c# (10)
Tengo una biblioteca de clase con algunos métodos de extensión escritos en C # y un sitio web antiguo escrito en VB.
Quiero llamar a mis métodos de extensión desde el código VB pero no aparecen en intelisense y obtengo errores de compilación cuando visito el sitio.
Obtuve todas las Importaciones requeridas porque otras clases contenidas en los mismos espacios de nombres están apareciendo bien en Intelisense.
Alguna sugerencia
EDITAR: Más información para ayudar con algunos comentarios.
mi implementación se ve así
//C# code compiled as DLL
namespace x.y {
public static class z {
public static string q (this string s){
return s + " " + s;
}
}
}
y mi uso como este
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.
... y un viejo sitio web escrito en VB.
¿Significa "viejo" aquí quizás que también usas una versión anterior de VB aquí? De todos modos, dado que los métodos de extensión son solo métodos vainilla estáticos (" Shared
") decorados con un atributo, debería poder llamarlos en cualquier caso.
Si esto no es posible, intente llamarlos "estilo de extensión" en una versión anterior de VB o está haciendo referencia a la versión incorrecta de su ensamblado C #.
Editar: ¿estás seguro de que estás importando todo el espacio de nombres, es decir, xy
y no solo x
? VB puede acceder a los espacios de nombres anidados más fácilmente que C # para que pueda usar las clases del espacio de nombres xy
usando el siguiente código en VB. Sin embargo, para que los métodos de extensión funcionen, se debe Import
la ruta completa .
Imports x
Dim x As New y.SomeClass()
Creo que he encontrado un problema similar : a VB.Net le complace compilar a través de los métodos de extensión y dejarlos que se deduzcan en el tiempo de ejecución si Option Strict
está desactivado.
Sin embargo, a VB.Net realmente no le gustan los métodos de extensión en tipos básicos. No puede extender Object
y no puede resolverlo si lo hace:
DO#
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");
Sin embargo, esto va mal en VB.Net:
Option Infer On
Option Explicit On
Option Strict Off
Imports NS
...
Dim r as String = "test"
r.Something()
Que se compila sin error, pero en tiempo de ejecución falla porque Something
no es un método de String
: el compilador no ha podido reemplazar el azúcar sintáctico del método de extensión con la llamada estática a Utility.Something
. Utility.Something
.
La pregunta es por qué? ¡A diferencia de C #, VB.Net no puede manejar ninguna extensión de Object
! El método de extensión válido en C # confunde el compilador VB.Net.
Como norma general de VB.Net, evitaría usar métodos de extensión con cualquiera de los tipos básicos de .Net ( Object
, String
, Integer
, etc.). También debe tener cuidado con Option Infer
ya que, mientras está activado por defecto en Visual Studio, está desactivado de forma predeterminada para compilaciones de línea de comandos, VBCodeProvider
y posiblemente en sitios web (según su web.config). Cuando está desactivado todo en VB.Net se considera un Object
y todos los métodos de extensión se dejarán hasta el tiempo de ejecución (y por lo tanto fallarán).
Creo que Microsoft realmente dejó caer la pelota cuando agregaron métodos de extensión a VB.Net, creo que fue una idea de último momento para intentar (y no) hacer que sea coherente con C #.
DE ACUERDO. Según el mensaje de error, definitivamente no está utilizando la versión más reciente de VB (¡VB 9!) O el error no está relacionado con este problema en absoluto porque entonces obtendría otro error si no se encuentra el método:
El error 1 ''q'' no es miembro de ''String''.
Dos cosas para verificar:
- Estás orientando .Net 3.5
- Estás haciendo referencia a la DLL
Algunas herramientas pueden sugerir incorrectamente métodos de extensión para proyectos que no los admiten.
Esto fue hace bastante tiempo y no puedo realmente cómo lo resolví, pero no hace falta decir que fue un error del usuario. Probablemente reinicie mi computadora y se fue.
Funciona para mí, aunque hay un par de peculiaridades. Primero, creé una biblioteca de clase C # que apunta a .NET 3.5. Este es el único código en el proyecto:
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);
}
}
}
Luego creé una aplicación de consola VB orientada a .NET 3.5 y agregué una referencia a mi proyecto C #. Cambié el nombre de Module1.vb a Test.vb, y aquí está el código:
Imports ExtensionLibrary
Module Test
Sub Main()
Console.WriteLine("Hello".CustomExtension())
End Sub
End Module
Esto compila y ejecuta. (Habría llamado el método Reverse () pero no estaba seguro de si VB podría tener mágicamente habilidades inversas en alguna parte, no soy un experto en VB por una tiza larga).
Inicialmente, no me ofrecieron ExtensionLibrary como una importación desde Intellisense. Incluso después de la construcción, la "Imports ExtensionLibrary" aparece atenuada y una bombilla ofrece la oportunidad de eliminar la supuestamente redundante importación. (Hacerlo rompe el proyecto.) Es posible que esto sea ReSharper en lugar de Visual Studio, fíjate.
Entonces, para abreviar, se puede hacer, y debería funcionar bien. Supongo que el problema es que no estás utilizando una versión anterior de VB o que tu proyecto no tiene como objetivo .NET 3.5.
Los métodos de extensión son solo azúcar sintáctico para métodos estáticos. Asi que
public static string MyExtMethod(this string s)
se puede invocar tanto en VB.NET como en C # con
MyExtMethod("myArgument")
Me encontré con el mismo problema, y podría haber tropezado accidentalmente con la solución. Si yo usé
x.y.r.q()
, arrojó el mismo error para mí también. Pero si importé xy, funcionó, entonces:
using x.y;
...
r.q()
estuvo bien.
Entonces, aparentemente tiene que importarlo en la declaración para que funcione.
No sé si puede llamarlos con la misma notación de puntos que usaría en C #, pero creo que los métodos de extensión estáticos aparecerían como funciones estáticas con el argumento de puño como tipo extendido. Entonces deberías poder llamar a la clase real en VB con:
StaticClass.ExtensionMethod(theString, arg1, ..., argN)
Donde en C # hubieras escrito:
theString.ExtensionMethod(arg1, ..., argN);
Con StaticClass es el nombre de la clase estática en la que definió sus métodos de extensión.
Imports x.y
''...''
Dim r As String = "greg"
Dim s As String = r.q() ''same as z.q(r)