Assembly Friend (C++)
Per il runtime applicabili, la funzionalità del linguaggio degli assembly Friend rende i tipi che sono in ambito o all'ambito dello spazio dei nomi globale in una parte dell'assembly accessibile a uno o più assembly client o.netmodule.
Tutti i runtime
Note
(Questa funzionalità del linguaggio non è supportata in tutti i runtime.)
Windows Runtime
Note
(Questa funzionalità del linguaggio non è supportata in Windows Runtime).
Requisiti
Opzione del compilatore: /ZW
Common Language Runtime
Note
Per rendere i tipi in ambito o all'ambito dello spazio dei nomi globale in una parte dell'assembly accessibile a un assembly client o.netmodule
Nel componente, specificare un attributo InternalsVisibleToAttributedell'assembly e passare il nome dell'assembly client o.netmodule che tipi di accesso all'ambito o in ambito globale dello spazio dei nomi nel componente.È possibile specificare gli assembly più client o.netmodule specificando gli attributi aggiuntivi.
Nell'assembly client o.netmodule, quando si fa riferimento l'assembly componente utilizzando #using, passa l'attributo di as_friend.Se si specifica l'attributo di as_friend per un assembly non specifica InternalsVisibleToAttribute, un'eccezione di runtime verrà generata un'eccezione se si tenta di accedere a un tipo in ambito o in ambito globale dello spazio dei nomi nel componente.
Un errore di compilazione un errore se l'assembly che contiene l'attributo di InternalsVisibleToAttribute non ha un nome sicuro ma l'assembly client che utilizza l'attributo di as_friend scegliere.
Sebbene i tipi in ambito e all'ambito dello spazio dei nomi globale possono essere definiti in un assembly client o.netmodule, l'accessibilità del membro attivo.Ad esempio, non è possibile accedere a un membro privato.
L'accesso a tutti i tipi in un assembly deve essere esplicitamente concesse.Ad esempio, l'assembly che C non può accedere a tutti i tipi dell'assembly A se l'assembly c fa riferimento l'assembly B e l'assembly B può accedere a tutti i tipi dell'assembly A.
Per informazioni su come specificare l'accessibilità dei tipi da un assembly, vedere Visibilità di tipi.
Per informazioni su come accesso, ovvero come assegnare un nome sicuro (molti-a-uno a assembly compilato utilizzando il compilatore di Visual C++, vedere Assembly con nome sicuro (firma degli assembly) (C++/CLI).
Come alternativa a utilizzare gli assembly Friend la funzionalità, è possibile utilizzare StrongNameIdentityPermission per limitare l'accesso ai singoli tipi.
Requisiti
Opzione del compilatore: /clr
Esempi
Il codice riportato di seguito viene definito un componente che specifica un assembly client che ha accesso ai tipi del 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 seguente si accede a un oggetto 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();
}
Output
Class1::Test_Public
L'esempio di codice seguente definisce un componente ma non viene specificato un assembly client che abbia accesso ai tipi del componente.
Si noti che il componente è collegata utilizzando /opt:noref.Questo assicura che i tipi privati vengono emessi nei metadati del componente, che non è necessario quando l'attributo di InternalsVisibleTo è presente.Per ulteriori 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");
}
};
Il codice riportato di seguito viene definito un client che le tenta di accedere a un oggetto privato tipo in un componente che non consente l'accesso ai tipi privati.A causa del comportamento di runtime, se si desidera rilevare l'eccezione, tentare di accedere a un oggetto privato tipo in una funzione di supporto.
// 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");
}
}
Output
caught an exception
Nell'esempio di codice riportato di seguito come creare un componente con nome sicuro che specifica un assembly client che avrà accesso ai tipi del 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 la componente deve specificare la chiave pubblica.Si consiglia di eseguire i comandi seguenti in sequenza a un prompt dei comandi 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 seguente si accede a un oggetto 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();
}
Output
Class1::Test_Public