MSDN上解釋Internal如下:
The internal keyword is an access modifier for types and type members. Internal types or members are accessible only within files in the same assembly.
即, 僅允許相同程序集內的代碼調用類型或成員.
那么是否可以調用這些internal的方法呢?
如果被調用的程序集, 在代碼中使用了InternalsVisibleToAttribute來標示一個或多個友元程序集, 那么這些被標為友元的程序集就可以訪問被調用程序集的internal方法. 下例是程序集A的代碼, 它宣布AssemblyB為友元程序集
// This file is for Assembly A. using System.Runtime.CompilerServices; using System; [assembly: InternalsVisibleTo("AssemblyB")] // The class is internal by default. class FriendClass { public void Test() { Console.WriteLine("Sample Class"); } } // Public class that has an internal method. public class ClassWithFriendMethod { internal void Test() { Console.WriteLine("Sample Method"); } }
更具體的一行代碼示例如下:
[assembly: InternalsVisibleTo("AssemblyB, PublicKey=32ab4ba45e0a69a1")]
那么如果我們要調用的是第三方人寫的代碼里的internal的方法, 怎么辦呢?
答案是使用反射.
下面是被調用的類的源代碼.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace internalclasstest { public class PubClass { public void Speak() { Console.WriteLine("PubClass speaks: You are so nice!"); } //Internal method internal void Mock() { Console.WriteLine("PubClass mocks: You suck!"); } } //Internal class class InternalClass { public void Speak() { Console.WriteLine("InternalClass speaks: I love my job!"); } void Moci() { Console.WriteLine("InternalClass speaks: I love Friday night!"); } } }
下面是使用反射並調用PubClass的Internal 函數Mock的代碼示例:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; namespace reflectionInternal { class Program { static void Main(string[] args) { Assembly asm = Assembly.LoadFile(@"E:\internalclasstest\bin\Debug\internalclasstest.dll"); Type t1 = asm.GetType("internalclasstest.PubClass"); ConstructorInfo t1Constructor = t1.GetConstructor(Type.EmptyTypes); Object oPubClass = t1Constructor.Invoke(new Object[] { }); MethodInfo oMethod = t1.GetMethod("Mock", BindingFlags.Instance | BindingFlags.NonPublic); oMethod.Invoke(oPubClass, new Object[]{}); } } }