web-dev-qa-db-fra.com

Le type existe dans 2 assemblies

J'ai créé deux assemblys .NET Interop à partir de deux DLL COM différentes. Les deux DLL COM contenaient un type nommé COMMONTYPE. Par conséquent, COMMONTYPE est maintenant exposé également à travers les deux assemblages Interop.

J'ai un troisième projet qui doit utiliser ces deux assemblages Interop et j'obtiens la fameuse erreur de compilation:

Le type <ABC> existe à la fois dans <Assembly1.dll> et <Assembly2.dll>

Étant donné que les DLL COM sont fournies par un fournisseur tiers, je n’ai pas accès au code source et j’écris une application console C #, ce qui signifie que je n’ai aucun fichier web.config où je pourrais ajouter la solution de contournement debug=false. Que puis-je faire?

50
Kou S Hal

Je sais que c'est vieux, mais il existe un moyen plus facile que la liste. Cela fonctionne lorsque vous référencez deux assemblys qui partagent des types avec le même nom et le même espace de noms exact.

Si vous cliquez avec le bouton droit de la souris sur la référence à votre DLL et sélectionnez Propriétés, vous verrez qu'il s'agit d'une propriété appelée "Alias".

 enter image description here

La valeur par défaut est "global". Pour l'une des assemblées en conflit, remplacez cette valeur par une autre. Dans l'exemple ci-dessous, je l'ai changé de "global" à "destination".

Ensuite, dans votre fichier de code, vous devrez utiliser le mot-clé extern pour utiliser cet alias en tant que espace de noms de niveau racine pour ces types. Dans cet exemple, placez le texte suivant en haut de votre fichier .cs:

extern alias destination

Maintenant, dans ce fichier, vous pouvez référencer les deux types. 

extern alias destination;
namespace Test
{
    public static class TestClass
    {
        public static void Success()
        {
            var foo = destination::Some.Duplicate.Namespace.SomeDuplicateType();
            var bar = Some.Duplicate.Namespace.SomeDuplicateType();
        }
    }
}
110
Tom

À moins que les espaces de noms des fournisseurs ne soient identiques (peu probable), les définitions de types seront réellement séparées à ce stade. Ce que vous devrez faire (et il s’agit parfois d’un PITA complet), c’est de créer un alias d’espace de nom dans votre instruction using plutôt que de simplement appliquer la déclaration carte blanche. Cela vous permettra de ré-identifier les espaces de noms:

using Vendor1 = Vendor.Namespace;
using Vendor2 = OtherVendor.Namespace;

...

Vendor1.COMMONTYPE blah = new Vendor1.COMMONTYPE();
Vendor2.COMMONTYPE blah2 = new Vendor2.COMMONTYPE();

Cela impliquera d'utiliser l'alias spécifique pour tous les types situés dans chaque espace de noms pour ces fournisseurs.

11
Joel Etherton

Ancienne question, mais option plus simple trouvée. Sélectionnez la référence que vous souhaitez utiliser. Sous les propriétés, modifiez les alias en "xyz" Maintenant dans la ligne de code, ajoutez en haut:

extern alias xyz;

puis ajoutez en utilisant:

using xyz.VENDOR2.Type;

ou une autre façon d'utiliser en utilisant:

using OtherNameSpace = xyz.VENDOR2.Type;

maintenant vous devriez pouvoir utiliser la référence explicitement comme ci-dessous:

var abc = new xyz.VENDOR2.Type.abc();

ou

var abc = new OtherNameSpace.abc();
10
Zunair

vous pouvez utiliser un alias pour les différents espaces de noms et/ou types:

voici à quoi cela ressemblerait:

using other = sssssss.a;
namespace ConsoleApplication1
{
    public class a 
    {
        public string ff { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            other s = new other();
            a b = new a();
        }
    }
}
namespace sssssss 
{

    public class a
    {
        public string ff { get; set; }
    }
}

MSDN

1
Igarioshka

Vous pouvez peut-être vous tromper en modifiant une namespace de l'un des assemblys. Dans ce cas, le nom qualifié complet d'un COMMONTYPE ne sera pas égal à un autre, et peut-être cela pourrait résoudre votre problème de conflit dans la 3ème DLL . 

J'espère que cela t'aides.

0
Tigran