Przyjazne zestawy (C++)
W przypadku odpowiednich środowisk uruchomieniowych funkcja języka przyjaznych zestawów sprawia, że typy, które znajdują się w zakresie przestrzeni nazw lub zakresie globalnym w składniku zestawu dostępnym dla co najmniej jednego zestawu klienta lub modułów .netmodules.
Wszystkie środowiska wykonawcze
Uwagi
(Ta funkcja języka nie jest obsługiwana we wszystkich środowiskach uruchomieniowych).
Środowisko wykonawcze systemu Windows
Uwagi
(Ta funkcja języka nie jest obsługiwana w środowisko wykonawcze systemu Windows).
Wymagania
Opcja kompilatora: /ZW
środowiska uruchomieniowe w trakcie wykonania
Uwagi
Aby tworzyć typy w zakresie przestrzeni nazw lub zakresie globalnym w składniku zestawu dostępnym dla zestawu klienta lub .netmodule
W składniku określ atrybut InternalsVisibleToAttributezestawu i przekaż nazwę zestawu klienta lub .netmodule, która będzie uzyskiwać dostęp do typów w zakresie przestrzeni nazw lub zakresie globalnym w składniku. Można określić wiele zestawów klienta lub modułów .netmodules, określając dodatkowe atrybuty.
W zestawie klienta lub w trybie .netmodule podczas odwoływać się do zestawu składników przy użyciu polecenia
#using
, przekażas_friend
atrybut . Jeśli określiszas_friend
atrybut zestawu, który nie określiInternalsVisibleToAttribute
, zostanie zgłoszony wyjątek środowiska uruchomieniowego, jeśli spróbujesz uzyskać dostęp do typu w zakresie przestrzeni nazw lub zakresie globalnym w składniku.
Błąd kompilacji spowoduje, że zestaw zawierający InternalsVisibleToAttribute atrybut nie ma silnej nazwy, ale zestaw klienta, który używa atrybutu as_friend
.
Mimo że typy w zakresie przestrzeni nazw i zakresie globalnym mogą być znane zestawowi klienta lub modułowi .netmodule, dostępność składowa jest nadal obowiązująca. Na przykład nie można uzyskać dostępu do prywatnego elementu członkowskiego.
Należy jawnie udzielić dostępu do wszystkich typów w zestawie. Na przykład zestaw C nie ma dostępu do wszystkich typów w zestawie A, jeśli zestaw C odwołuje się do zestawu B i zestaw B ma dostęp do wszystkich typów w zestawie A.
Aby uzyskać informacje o sposobie podpisywania — czyli nadawaniu silnej nazwy — zestawowi kompilatorowi języka Microsoft C++, zobacz Zestawy silnych nazw (podpisywanie zestawów) (C++/CLI).
Alternatywą dla używania funkcji zestawów przyjaznych jest StrongNameIdentityPermission ograniczenie dostępu do poszczególnych typów.
Wymagania
Opcja kompilatora: /clr
Przykłady
Poniższy przykład kodu definiuje składnik, który określa zestaw klienta, który ma dostęp do typów w składniku.
// 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");
}
};
Następny przykład kodu uzyskuje dostęp do typu prywatnego w składniku.
// 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
Następny przykład kodu definiuje składnik, ale nie określa zestawu klienta, który będzie miał dostęp do typów w składniku.
Zwróć uwagę, że składnik jest połączony przy użyciu / opt:noref. Gwarantuje to, że typy prywatne są emitowane w metadanych składnika, co nie jest wymagane, gdy InternalsVisibleTo
atrybut jest obecny. Aby uzyskać więcej informacji, zobacz /OPT (Optymalizacje).
// 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");
}
};
Poniższy przykład kodu definiuje klienta, który próbuje uzyskać dostęp do typu prywatnego w składniku, który nie daje dostępu do jego typów prywatnych. Ze względu na zachowanie środowiska uruchomieniowego, jeśli chcesz przechwycić wyjątek, musisz spróbować uzyskać dostęp do typu prywatnego w funkcji pomocniczej.
// 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
W następnym przykładzie kodu pokazano, jak utworzyć składnik o silnej nazwie, który określa zestaw klienta, który będzie miał dostęp do typów w składniku.
// 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");
}
};
Zwróć uwagę, że składnik musi określić jego klucz publiczny. Zalecamy uruchomienie następujących poleceń sekwencyjnie w wierszu polecenia w celu utworzenia pary kluczy i pobrania klucza publicznego:
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
Następny przykład kodu uzyskuje dostęp do typu prywatnego w składniku silnej nazwy.
// 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
Zobacz też
Component Extensions dla platform środowiska uruchomieniowego