J'ai deux fichiers DLL qui ont le même espace de noms mais qui ont des méthodes et des types différents. Comment puis-je référencer les deux DLL dans mon projet et utiliser leurs méthodes et types?
Par ailleurs, ces deux DLL ont des méthodes et des types avec le même nom mais une implémentation différente et des méthodes et des types uniques.
Il n'y a rien de spécial à faire - il suffit de les référencer et d'utiliser les types. Les espaces de noms peuvent s'étendre sur plusieurs assemblages sans problème, car ce ne sont pas vraiment des types opaques. Un espace de noms n'est qu'un moyen d'ajouter un préfixe commun à tous les types qu'il contient, vous permettant d'avoir plusieurs types du même nom sous différents espaces de noms. (Le framework ne les voit pas comme ayant les mêmes noms, car il voit le nom "complet" de tout - qui a un alias et un espace de noms attachés à l'avant.)
Dans les rares cas où vous référencez 2 assemblys qui ont les mêmes noms de type et les mêmes espaces de noms (tels que 2 versions différentes de la même dll) - vous pouvez distinguer l'assembly à utiliser pour un type donné en utilisant un alias. L'alias par défaut pour toutes les références est global
, mais vous pouvez spécifier votre propre alias pour n'importe quel assembly lorsque vous le référencez (à l'aide d'un commutateur de compilation - ou utilisez simplement la boîte de propriétés dans Visual Studio) - et disposez d'un extern alias <name>
clause en haut de votre fichier de code où vous l'utilisez - vous accéderez aux types de différents assemblys avec <name>::MyNamespace.Type
Si vous avez 2 types avec exactement le même nom (notez que le nom inclut l'espace de noms) mais dans différentes DLL et que vous souhaitez les utiliser tous les deux, vous pouvez le faire.
Réponse courte
Vous avez du type Acme.Foo
dans 2 DLL différentes et vous souhaitez les utiliser. Donnez à la référence un alias dans la fenêtre des propriétés de référence (Affichage | Fenêtre Propriétés) puis utilisez-la comme ceci:
extern alias TheAliasYouGaveTheReference
TheAliasYouGaveTheReference::Acme.Foo f = new
TheAliasYouGaveTheReference::Acme.Foo();
L'espace de noms par défaut est global
pour tout programme C # mais notez ci-dessus que nous utilisons l'alias que nous avons créé au lieu de global
.
La meilleure approche consiste à [~ # ~] et non [~ # ~] à entrer dans une situation comme celle-ci en premier lieu, si les deux assemblages vous appartiennent, alors ne créez pas 2 types avec exactement le même nom dans exactement le même espace de noms. Mais parfois, nous ne contrôlons pas le code source, pour ces périodes, la solution ci-dessus peut être utilisée.
Réponse longue
Je copie la plupart de l'article de ici donc il est enregistré ici au cas où l'article ne serait plus disponible.
Comment vous situez-vous dans une telle situation?
Tout d'abord, voici comment vous pouvez reproduire le scénario afin qu'il soit vraiment clair de quoi nous parlons:
Remplacez le code du modèle dans Class1.cs par ce qui suit:
using System;
namespace Acme
{
public class Foo
{
public void Bar()
{
Console.WriteLine("Bar");
}
}
}
Cliquez avec le bouton droit sur la solution dans l'Explorateur de solutions et sélectionnez Ajouter | Nouveau projet
Remplacez le code dans Class1.cs par ce qui suit:
using System;
namespace Acme
{
public class Foo
{
public void Bar()
{
Console.WriteLine("Bar");
}
public void Goo()
{
Console.WriteLine("Goo");
}
}
}
Utilisation du type dans Application
Ok maintenant nous avons 2 assemblages différents contenant Acme.Foo
. Créons maintenant une application console et essayons de les utiliser chacune.
Ajoutez la ligne suivante à Main dans le type de programme du projet Consumer:
Acme.Foo f = new Acme.Foo();
Générez la solution via Ctrl + Maj + B (ou F6) Notez que vous obtenez deux erreurs de génération [comme indiqué ci-dessous]:
Le correctif
Voici comment nous pouvons y remédier:
Ajoutez la directive suivante en haut de Program.cs dans le projet Consumer:
extern alias FooVersion1;
Changez l'utilisation d'Acme.Foo pour:
FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
f.Bar();
Notez que lorsque vous tapez "f", la liste d'achèvement ne contient que les méthodes de FooVersion1 d'Acme.Foo (notamment elle n'inclut pas Goo)
Enfin, ajoutez le code suivant sous f.Bar () dans Program.cs du projet Consumer:
Acme.Foo f2 = new Acme.Foo();
f2.Goo();
Notez que la liste d'achèvement de f2 contient Goo.
vous pouvez utiliser la fonction d'alias de l'option de compilation/reference (Import Metadata) (Options du compilateur C #) pour résoudre vos problèmes, lisez ici pour plus de détails