Question

J'ai une bibliothèque de classes avec des méthodes d'extension écrites en C # et un ancien site Web écrit en VB.

Je souhaite appeler mes méthodes d'extension à partir du code VB, mais elles n'apparaissent pas dans intelisense et je reçois des erreurs de compilation lorsque je visite le site.

J'ai tous les Importations requises, car d'autres classes contenues dans les mêmes espaces de noms apparaissent parfaitement dans Intelisense.

Toutes les suggestions

MODIFIER: plus d'informations pour vous aider avec certains commentaires.

mon implémentation ressemble à ceci

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

    }
}

et mon utilisation comme ça

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.
Était-ce utile?

La solution

Cela fonctionne pour moi, bien qu'il y ait quelques bizarreries. Tout d'abord, j'ai créé une bibliothèque de classe C # ciblant .NET 3.5. Voici le seul code du projet:

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

Ensuite, j'ai créé une application de console VB ciblant .NET 3.5 et ajouté une référence à mon projet C #. J'ai renommé Module1.vb en Test.vb, et voici le code:

Imports ExtensionLibrary

Module Test

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

End Module

Ceci compile et s'exécute. (J'aurais appelé la méthode Reverse () mais je ne savais pas si VB aurait déjà des capacités inverses comme par magie - je ne suis pas un expert de VB à la longue craie.)

Initialement, ExtensionLibrary ne m'était pas proposé comme importation d'Intellisense. Même après la construction, le dossier "Imports ExtensionLibrary" est grisé et une ampoule offre la possibilité de supprimer l’importation supposée redondante. (Cela casse le projet.) Il est possible que ce soit ReSharper plutôt que Visual Studio, remarquez.

Donc, pour résumer une longue histoire, cela peut être fait et cela devrait fonctionner correctement. Je ne suppose pas que le problème est que vous utilisez une ancienne version de VB ou que votre projet ne cible pas .NET 3.5?

Comme indiqué dans les commentaires: il existe un problème supplémentaire, à savoir que les méthodes d'extension ne sont pas trouvées lorsque le type de compilation de la cible, au moment de la compilation est Objet .

Autres conseils

Les méthodes d'extension ne sont que du sucre syntaxique pour les méthodes statiques. Donc

public static string MyExtMethod(this string s)

peut être appelé à la fois en VB.NET et en C # avec

MyExtMethod("myArgument")

OK En fonction du message d'erreur, vous n'utilisez certainement pas la version la plus récente de VB (VB 9!) Ou l'erreur n'est pas du tout liée à ce problème car vous obtiendrez une autre erreur si la méthode n'a pas été trouvé:

  

Erreur 1 'q' n'est pas un membre de 'String'.

Imports x.y

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

Je pense avoir rencontré un problème similaire : VB.Net est assez heureux de compiler via des méthodes d'extension et de les laisser. à inférer au moment de l'exécution si Option Strict est désactivé.

Cependant, VB.Net ne semble pas vraiment aimer les méthodes d’extension sur les types de base. Vous ne pouvez pas étendre Object et il ne peut pas le résoudre si vous effectuez:

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

Cependant, cela ne va pas dans VB.Net:

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

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

Qui compile sans erreur, mais au moment de l'exécution échoue car quelque chose n'est pas une méthode de String - le compilateur n'a pas réussi à remplacer le sucre syntaxique de la méthode d'extension par l'appel statique à Utility.Quelque chose .

La question est pourquoi? Contrairement à C #, VB.Net ne peut gérer aucune extension de Object ! La méthode d'extension valide en C # confond le compilateur VB.Net.

En règle générale, je ne voudrais pas utiliser de méthodes d'extension avec les types de base .Net ( Objet , String , Entier , etc). Vous devez également faire attention avec Option Infer car, lorsqu'il est activé par défaut dans Visual Studio, il est désactivé par défaut pour les compilations en ligne de commande, VBCodeProvider , et éventuellement dans les sites Web (en fonction sur votre web.config). Lorsqu'il est désactivé, tout dans VB.Net est considéré comme un objet et toutes les méthodes d'extension sont conservées jusqu'au moment de l'exécution (et échouent donc).

Je pense que Microsoft a vraiment laissé tomber la balle quand ils ont ajouté des méthodes d'extension à VB.Net. Je pense que ce fut une réflexion après coup d'essayer (et d'échouer) de le rendre cohérent avec C #.

Je ne sais pas si vous pouvez les appeler avec la même notation de points que vous le feriez en C #, mais je penserais que les méthodes d’extension statique s’afficheraient sous forme de fonctions statiques avec l’argument fist comme type étendu. Vous devriez donc pouvoir appeler la classe réellement en VB avec:

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

Où, en C #, vous venez d'écrire:

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

StaticClass étant le nom de la classe statique dans laquelle vous avez défini vos méthodes d'extension.

  

… et un ancien site Web écrit en VB.

Est-ce que “vieux” ici implique peut-être que vous utilisez également une ancienne version de VB ici? Quoi qu’il en soit, les méthodes d’extension ne sont que des méthodes statiques vanilles (“ Shared ”) décorées avec un attribut, vous devriez pouvoir les appeler dans tous les cas.

Si ce n'est pas possible, essayez de les appeler "style d'extension" dans une ancienne version de VB ou faites référence à la mauvaise version de votre assembly C #.

Éditer: êtes-vous sûr que vous êtes Importer dans l’espace de noms entier , c’est-à-dire xy et pas seulement x ? VB peut accéder aux espaces de noms imbriqués plus facilement que C #, vous pouvez donc utiliser les classes de l'espace de noms x.y à l'aide du code suivant en VB. Cependant, pour que les méthodes d’extension fonctionnent, le chemin complet doit être Importer éd.

Imports x
Dim x As New y.SomeClass()

Deux choses à vérifier:

  1. Vous ciblez .Net 3.5
  2. Vous faites référence à la DLL

Certains outils peuvent suggérer de manière incorrecte des méthodes d'extension pour les projets qui ne les prennent pas en charge.

J'ai rencontré le même problème et j'aurais peut-être trouvé accidentellement la solution. Si j'ai utilisé

x.y.r.q()

, cela m'a aussi causé la même erreur. Mais si j'ai importé x.y, cela a fonctionné, donc:

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

était bien.

Donc, apparemment, vous devez l'importer dans la déclaration pour que cela fonctionne.

C’était il ya un certain temps et je ne sais pas vraiment comment je l’ai résolu, mais inutile de préciser que c’était une erreur de l’utilisateur. J'ai probablement redémarré mon ordinateur et c'est parti.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top