Czasami zdarza się, że jesteśmy świadomi istnienia jakiejś funkcjonalności, jednak wredny twórca biblioteki bezwstydnie ją przed nami ukrył. A my ją odkryliśmy na przykład przy pomocy Reflectora.
Zasymulujmy taką sytuację. Wyobraźmy sobie bibliotekę z klasą Jarek oznaczoną jako internal. Klasa Jarek z kolei chowa przed nami bardzo ciekawą funkcjonalność - zakładanie konta w banku za pośrednictwem nieistotnej dla nas klasy Bank:
1: namespace JarekLibrary
2: {
3: internal class Jarek
4: {
5: private void CreateBankAccount()
6: {
7: Console.WriteLine("<płacze_i_krzyczy>");
8: Bank.CreateAccount(this);
9: Console.WriteLine("<lecz_zalozyl>");
10: }
11: }
12: }
My, podli użytkownicy, bardzo chcemy zmusić Jarka do założenia konta. Umożliwia nam to mechanizm refleksji. Poniższy kod pozostawiam bez komentarza - jest to działająca metoda a po szczegóły odsyłam MSDN, żeby bezsensownie nie przepisywać tutaj dokumentacji:
1: static void Main(string[] args)
2: {
3: Assembly jarekLibrary = Assembly.LoadFrom("JarekLibrary.dll");
4: Type jarekType = jarekLibrary.GetType("JarekLibrary.Jarek");
5: object jarekInstance = Activator.CreateInstance(jarekType);
6: MethodInfo createAccountMethod = jarekType.GetMethod("CreateBankAccount", BindingFlags.NonPublic | BindingFlags.Instance);
7: createAccountMethod.Invoke(jarekInstance, null);
8: }
W efekcie zobaczymy na konsoli słodki tekst informujący o sukcesie.
P.S. Wszekie skojarzenia z faktycznym stanem rzeczywistości oczywiście niezamierzone - równie dobrze można było nazwać klasę Bonifacy, ale nie wyglądałoby to tak ślicznie.