在C#中使用反射調用internal的方法


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[]{});
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM