Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Für anwendbare Laufzeiten ermöglicht das Sprachfeature Friend Assemblies den Zugriff auf Typen, die sich im Namensraum oder globalen Bereich einer Assemblykomponente befinden, durch eine oder mehrere Clientassemblies oder .netmodules.
Alle Laufzeiten
Anmerkungen
(Dieses Sprachfeature wird in allen Laufzeiten nicht unterstützt.)
Windows-Runtime
Anmerkungen
(Dieses Sprachfeature wird in der Windows-Runtime nicht unterstützt.)
Anforderungen
Compileroption: /ZW
Übersicht: Common Language Runtime (CLR)
Anmerkungen
So machen Sie Typen auf Namensraumebene oder globaler Ebene in einer Assembly zugänglich, damit sie von einer Clientassembly oder einem .NET-Module genutzt werden können.
Geben Sie in der Komponente ein Assembly-Attribut InternalsVisibleToAttribute an, und übergeben Sie den Namen der Client-Assembly oder des .NET-Moduls, das auf Typen auf Namespace-Ebene oder globaler Ebene in der Komponente zugreift. Sie können mehrere Clientassemblys oder .netmodule angeben, indem Sie zusätzliche Attribute angeben.
In der Clientassembly oder dem .netmodule, wenn Sie mithilfe von
#usingauf die Komponentenassembly verweisen, übergeben Sie dasas_friend-Attribut. Wenn Sie dasas_friend-Attribut für eine Assembly angeben, ohne das AttributInternalsVisibleToAttribute, wird eine Laufzeitausnahme ausgelöst, wenn Sie versuchen, auf einen Typ im Namensraum oder globalen Bereich der Komponente zuzugreifen.
Ein Buildfehler tritt auf, wenn die Assembly, die das InternalsVisibleToAttribute-Attribut enthält, keinen starken Namen hat, aber die Client-Assembly, die das as_friend-Attribut verwendet, schon.
Obwohl Typen im Namespace-Bereich und im globalen Bereich einer Client-Assembly oder einem .NET-Modul bekannt sein können, bleibt die Zugänglichkeit von Membern dennoch wirksam. Sie können beispielsweise nicht auf ein privates Mitglied zugreifen.
Der Zugriff auf alle Typen in einer Assembly muss explizit gewährt werden. Assembly C hat beispielsweise keinen Zugriff auf alle Typen in Assembly A, wenn Assembly C auf Assembly B verweist und Assembly B Zugriff auf alle Typen in Assembly A hat.
Informationen zum Signieren – d. h. zum Zuweisen eines starken Namens – einer Assembly, die mithilfe des Microsoft C++-Compilers erstellt wird, finden Sie unter "Assemblysignierung mit starkem Namen" (C++/CLI).
Als Alternative zur Verwendung der Funktion "Friend Assemblies" können Sie mit StrongNameIdentityPermission den Zugriff auf einzelne Typen einschränken.
Anforderungen
Compileroption: /clr
Beispiele
Im folgenden Codebeispiel wird eine Komponente definiert, die eine Clientassembly angibt, die Zugriff auf die Typen in der Komponente hat.
// 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");
}
};
Im nächsten Codebeispiel wird auf einen privaten Typ in der Komponente zugegriffen.
// 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
Im nächsten Codebeispiel wird eine Komponente definiert, aber keine Clientassembly angegeben, die Zugriff auf die Typen in der Komponente hat.
Beachten Sie, dass die Komponente mithilfe von /opt:noref verknüpft ist. Dadurch wird sichergestellt, dass private Typen in den Metadaten der Komponente ausgegeben werden, was nicht erforderlich ist, wenn das InternalsVisibleTo Attribut vorhanden ist. Weitere Informationen finden Sie unter /OPT (Optimierungen).
// 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");
}
};
Im folgenden Codebeispiel wird ein Client definiert, der versucht, auf einen privaten Typ in einer Komponente zuzugreifen, die keinen Zugriff auf seine privaten Typen ermöglicht. Aufgrund des Verhaltens der Laufzeit müssen Sie versuchen, auf einen privaten Typ in einer Hilfsfunktion zuzugreifen, wenn Sie die Ausnahme abfangen möchten.
// 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
Das nächste Codebeispiel zeigt, wie Sie eine Komponente mit starkem Namen erstellen, die eine Clientassembly angibt, die Zugriff auf die Typen in der Komponente hat.
// 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");
}
};
Beachten Sie, dass die Komponente ihren öffentlichen Schlüssel angeben muss. Es wird empfohlen, die folgenden Befehle sequenziell an einer Eingabeaufforderung auszuführen, um ein Schlüsselpaar zu erstellen und den öffentlichen Schlüssel abzurufen:
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
Im nächsten Codebeispiel wird auf einen privaten Typ in einer stark benannten Komponente zugegriffen.
// 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