Pregunta

Tengo una biblioteca de clases 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.

Tengo todos los Importar necesarios porque otras clases contenidas en los mismos espacios de nombres aparecen bien en Intelisense.

Cualquier 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.
¿Fue útil?

Solución

Funciona para mí, aunque hay un par de caprichos. Primero, creé una biblioteca de clases de C # orientada a .NET 3.5. Aquí está 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 de VB orientada a .NET 3.5 y agregué una referencia a mi proyecto de 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 al método Reverse () pero no estaba seguro de que VB pudiera tener mágicamente habilidades de reversa en algún lugar, 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 " está en gris y una bombilla ofrece la oportunidad de eliminar la importación supuestamente redundante. (Al hacerlo, se rompe el proyecto.) Es posible que esto sea ReSharper en lugar de Visual Studio, claro.

Para recortar una larga historia, puede hacerse, y debería funcionar bien. Supongo que el problema no es que esté utilizando una versión antigua de VB o su proyecto no está apuntando a .NET 3.5?

Como se señaló en los comentarios: hay una peculiaridad adicional, que es que los métodos de extensión no se encontrarán cuando el tipo de tiempo de compilación del objetivo es Object .

Otros consejos

Los métodos de extensión son solo azúcar sintáctica para métodos estáticos. Así que

public static string MyExtMethod(this string s)

se puede llamar tanto en VB.NET como en C # con

MyExtMethod("myArgument")

OK. De acuerdo con el mensaje de error, definitivamente no está usando 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 el método no se encontró:

  

Error 1 'q' no es miembro de 'String'.

Imports x.y

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

Creo que encontré un problema similar : VB.Net está muy contenta de compilar a través de métodos de extensión y dejarlos se deducirá en 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 los tipos básicos. No puede extender Object y no puede resolverlo si lo hace:

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

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

Se compila sin error, pero en el 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 .

La pregunta es ¿por qué? Bueno, a diferencia de C #, VB.Net no puede manejar ninguna extensión para Object . El método de extensión válido en C # confunde el compilador VB.Net.

Como regla general de VB.Net, evitaría usar métodos de extensión con cualquiera de los tipos .Net básicos ( Object , String , Integer , etc). También debe tener cuidado con Option Infer ya que mientras está activado de forma predeterminada en Visual Studio, está desactivado de forma predeterminada para las compilaciones de línea de comandos, VBCodeProvider , y posiblemente en los sitios web (dependiendo en su web.config). Cuando está apagado, 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 intentar (y fallar) hacerla compatible con C #.

No sé si se pueden llamar en la misma notación de puntos que en C #, pero creo que los métodos de extensión estática se mostrarían como funciones estáticas con el primer argumento como tipo extendido. Así que deberías poder llamar a la clase en realidad en VB con:

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

¿Dónde en C # habrías 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.

  

... y un sitio web antiguo escrito en VB.

¿Acaso "antiguo" aquí implica quizás que también usas una versión antigua de VB aquí? De todos modos, dado que los métodos de extensión son solo métodos estáticos vainilla (" Shared ") decorados con un atributo, usted debería poder llamarlos en cualquier caso.

Si esto no es posible, intenta llamarlos "estilo de extensión" en una versión antigua de VB o estás haciendo referencia a la versión incorrecta de tu ensamblaje de C #.

Editar: ¿estás seguro de que estás Importar con el espacio de nombres completo , es decir, xy y no solo x ? VB puede acceder a los espacios de nombres anidados más fácilmente que C #, por lo que puede usar clases del espacio de nombres x.y usando el siguiente código en VB. Sin embargo, para que los métodos de extensión funcionen, la ruta completa debe ser Importar ed.

Imports x
Dim x As New y.SomeClass()

Dos cosas para verificar:

  1. Estás apuntando a .Net 3.5
  2. Estás haciendo referencia a la DLL

Algunas herramientas pueden sugerir incorrectamente métodos de extensión para proyectos que no los admiten.

Me encontré con el mismo problema, y ??accidentalmente podría haber encontrado la solución. Si yo use

x.y.r.q()

, también me tiró el mismo error. Pero si importé x.y, funcionó, por lo que:

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

estaba bien.

Aparentemente, tienes que importarlo en la declaración para que funcione.

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 reinicié mi computadora y se fue.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top