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來標示一個或多個friend 組件, 那麼這些被標為友元的程式集就可以訪問被調用程式集的internal方法. 下例是程式集A的代碼, 它宣布AssemblyB為friend 組件
// 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[]{}); } }}
資料來源:
internal (C# Reference)
http://msdn.microsoft.com/en-us/library/7c5ka91b%28VS.80%29.aspx
Friend Assemblies (C# and Visual Basic)
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
Accessing internal members via System.Reflection?
http://stackoverflow.com/questions/171332/accessing-internal-members-via-system-reflection
Using reflection to call an internal method
http://www.codeproject.com/Messages/1635613/Using-reflection-to-call-an-internal-method.aspx
MethodBase.Invoke Method (Object, Object[])
http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx
BindingFlags Enumeration
http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx