Assembly Friend (C++)

Per i runtime applicabili, la funzionalità del linguaggio friend assembly rende i tipi che si trovano nell'ambito dello spazio dei nomi o nell'ambito globale in un componente assembly accessibile a uno o più assembly client o .netmodules.

Tutti i runtime

Osservazioni:

Questa funzionalità del linguaggio non è supportata in tutti i runtime.

Windows Runtime

Osservazioni:

Questa funzionalità del linguaggio non è supportata in Windows Runtime.

Requisiti

Opzione del compilatore: /ZW

Common Language Runtime

Osservazioni:

Per rendere i tipi nell'ambito dello spazio dei nomi o nell'ambito globale in un componente assembly accessibile a un assembly client o a .netmodule

  1. Nel componente specificare un attributo InternalsVisibleToAttributeassembly e passare il nome dell'assembly client o .netmodule che accederà ai tipi nell'ambito dello spazio dei nomi o nell'ambito globale del componente. È possibile specificare più assembly client o .netmodules specificando attributi aggiuntivi.

  2. Nell'assembly client o in .netmodule, quando si fa riferimento all'assembly del componente usando #using, passare l'attributo as_friend . Se si specifica l'attributo per un assembly che non specifica InternalsVisibleToAttribute, verrà generata un'eccezione di runtime se si tenta di accedere a un tipo nell'ambito as_friend dello spazio dei nomi o nell'ambito globale nel componente.

Se l'assembly che contiene l'attributo InternalsVisibleToAttribute non ha un nome sicuro ma l'assembly client che usa l'attributo as_friend , verrà generato un errore di compilazione.

Anche se i tipi nell'ambito dello spazio dei nomi e nell'ambito globale possono essere noti a un assembly client o a .netmodule, l'accessibilità dei membri è ancora attiva. Ad esempio, non è possibile accedere a un membro privato.

L'accesso a tutti i tipi in un assembly deve essere concesso in modo esplicito. Ad esempio, l'assembly C non ha accesso a tutti i tipi nell'assembly A se l'assembly C fa riferimento all'assembly B e l'assembly B ha accesso a tutti i tipi nell'assembly A.

Per informazioni su come firmare, ovvero come assegnare un nome sicuro a , un assembly compilato usando il compilatore Microsoft C++, vedere Assembly con nome sicuro (firma di assembly) (C++/CLI).

In alternativa all'uso della funzionalità di assembly Friend, è possibile usare StrongNameIdentityPermission per limitare l'accesso ai singoli tipi.

Requisiti

Opzione del compilatore: /clr

Esempi

Nell'esempio di codice seguente viene definito un componente che specifica un assembly client che ha accesso ai tipi nel componente.

// friend_assemblies.cpp
// compile by using: /clr /LD
using namespace System::Runtime::CompilerServices;
using namespace System;
// an assembly attribute, not bound to a type
[assembly:InternalsVisibleTo("friend_assemblies_2")];

ref class Class1 {
public:
   void Test_Public() {
      Console::WriteLine("Class1::Test_Public");
   }
};

L'esempio di codice successivo accede a un tipo privato nel componente.

// friend_assemblies_2.cpp
// compile by using: /clr
#using "friend_assemblies.dll" as_friend

int main() {
   Class1 ^ a = gcnew Class1;
   a->Test_Public();
}
Class1::Test_Public

L'esempio di codice successivo definisce un componente, ma non specifica un assembly client che avrà accesso ai tipi nel componente.

Si noti che il componente è collegato tramite /opt:noref. In questo modo si garantisce che i tipi privati vengano generati nei metadati del componente, che non sono necessari quando l'attributo InternalsVisibleTo è presente. Per altre informazioni, vedere /OPT (Ottimizzazioni).

// friend_assemblies_3.cpp
// compile by using: /clr /LD /link /opt:noref
using namespace System;

ref class Class1 {
public:
   void Test_Public() {
      Console::WriteLine("Class1::Test_Public");
   }
};

Nell'esempio di codice seguente viene definito un client che tenta di accedere a un tipo privato in un componente che non concede l'accesso ai tipi privati. A causa del comportamento del runtime, se si vuole intercettare l'eccezione, è necessario tentare di accedere a un tipo privato in una funzione helper.

// friend_assemblies_4.cpp
// compile by using: /clr
#using "friend_assemblies_3.dll" as_friend
using namespace System;

void Test() {
   Class1 ^ a = gcnew Class1;
}

int main() {
   // to catch this kind of exception, use a helper function
   try {
      Test();
   }
   catch(MethodAccessException ^ e) {
      Console::WriteLine("caught an exception");
   }
}
caught an exception

Nell'esempio di codice seguente viene illustrato come creare un componente con nome sicuro che specifica un assembly client che avrà accesso ai tipi nel componente.

// friend_assemblies_5.cpp
// compile by using: /clr /LD /link /keyfile:friend_assemblies.snk
using namespace System::Runtime::CompilerServices;
using namespace System;
// an assembly attribute, not bound to a type

[assembly:InternalsVisibleTo("friend_assemblies_6, PublicKey=00240000048000009400000006020000002400005253413100040000010001000bf45d77fd991f3bff0ef51af48a12d35699e04616f27ba561195a69ebd3449c345389dc9603d65be8cd1987bc7ea48bdda35ac7d57d3d82c666b7fc1a5b79836d139ef0ac8c4e715434211660f481612771a9f7059b9b742c3d8af00e01716ed4b872e6f1be0e94863eb5745224f0deaba5b137624d7049b6f2d87fba639fc5")];

private ref class Class1 {
public:
   void Test_Public() {
      Console::WriteLine("Class1::Test_Public");
   }
};

Si noti che il componente deve specificare la chiave pubblica. È consigliabile eseguire i comandi seguenti in sequenza al prompt dei comandi per creare una coppia di chiavi e ottenere la chiave pubblica:

sn -d friend_assemblies.snk

sn -k friend_assemblies.snk

sn -i friend_assemblies.snk friend_assemblies.snk

sn -pc friend_assemblies.snk key.publickey

sn -tp key.publickey

L'esempio di codice successivo accede a un tipo privato nel componente con nome sicuro.

// friend_assemblies_6.cpp
// compile by using: /clr /link /keyfile:friend_assemblies.snk
#using "friend_assemblies_5.dll" as_friend

int main() {
   Class1 ^ a = gcnew Class1;
   a->Test_Public();
}
Class1::Test_Public

Vedi anche

Estensioni componenti per le piattaforme runtime