1. 程式人生 > >C#反射 獲取程式集資訊和通過類名建立類例項

C#反射 獲取程式集資訊和通過類名建立類例項

C#反射獲取程式集資訊和通過類名建立類例項 。

System.Reflection 名稱空間:包含通過檢查託管程式碼中程式集、模組、成員、引數和其他實體的元資料來檢索其相關資訊的型別。

Assembly 類:表示一個程式集,它是一個可重用、無版本衝突並且可自我描述的公共語言執行庫應用程式構造塊。

1、反射獲取程式集資訊

1.1 建立AssemblyResult.cs類,用於儲存結果

/// <summary>
/// 反射結果類
/// </summary>
public class AssemblyResult
{
    /// <summary>
    /// 程式集名稱
    /// </summary>
    public List<string> AssemblyName { get; set; }

    /// <summary>
    /// 類名
    /// </summary>
    public List<string> ClassName { get; set; }

    /// <summary>
    /// 類的屬性
    /// </summary>
    public List<string> Properties { get; set; }

    /// <summary>
    /// 類的方法
    /// </summary>
    public List<string> Methods { get; set; }
}

1.2 建立AssemblyHandler.cs反射處理類

注意:要引用System.Reflection 名稱空間。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace MyStudyFrom
{
    /// <summary>
    /// 反射處理類
    /// </summary>
    public class AssemblyHandler
    {
        string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"/MyDLL/";

        /// <summary>
        /// 獲取程式集名稱列表
        /// </summary>
        public AssemblyResult GetAssemblyName()
        {
            AssemblyResult result = new AssemblyResult();
            string[] dicFileName = Directory.GetFileSystemEntries(path);
            if(dicFileName!=null)
            {
                List<string> assemblyList = new List<string>();
                foreach(string name in dicFileName)
                {
                    assemblyList.Add(name.Substring(name.LastIndexOf('/') + 1));
                }
                result.AssemblyName = assemblyList;
            }
            return result;
        }

        /// <summary>
        /// 獲取程式集中的類名稱
        /// </summary>
        /// <param name="assemblyName">程式集</param>
        public AssemblyResult GetClassName(string assemblyName)
        {
            AssemblyResult result = new AssemblyResult();
            if (!String.IsNullOrEmpty(assemblyName))
            {
                assemblyName = path + assemblyName;
                Assembly assembly = Assembly.LoadFrom(assemblyName);
                Type[] ts = assembly.GetTypes();
                List<string> classList = new List<string>();
                foreach (Type t in ts)
                {
                    //classList.Add(t.Name);
                    classList.Add(t.FullName);
                }
                result.ClassName = classList;
            }
            return result;
        }

        /// <summary>
        /// 獲取類的屬性、方法
        /// </summary>
        /// <param name="assemblyName">程式集</param>
        /// <param name="className">類名</param>
        public AssemblyResult GetClassInfo(string assemblyName, string className)
        {
            AssemblyResult result = new AssemblyResult();
            if (!String.IsNullOrEmpty(assemblyName) && !String.IsNullOrEmpty(className))
            {
                assemblyName = path + assemblyName;
                Assembly assembly = Assembly.LoadFrom(assemblyName);
                Type type = assembly.GetType(className,true,true);
                if (type != null)
                {
                    //類的屬性
                    List<string> propertieList = new List<string>();
                    PropertyInfo[] propertyinfo = type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                    foreach (PropertyInfo p in propertyinfo)
                    {
                        propertieList.Add(p.ToString());
                    }
                    result.Properties = propertieList;

                    //類的方法
                    List<string> methods = new List<string>();
                    MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    foreach (MethodInfo mi in methodInfos)
                    {
                        methods.Add(mi.Name);
                        //方法的引數
                        //foreach (ParameterInfo p in mi.GetParameters())
                        //{

                        //}
                        //方法的返回值
                        //string returnParameter = mi.ReturnParameter.ToString();
                    }
                    result.Methods = methods;
                }
            }
            return result;
        }
    }
}

2、通過類名建立類例項

2.1、假設你要反射一個 DLL 中的類,並且沒有引用它(即未知的型別):
Assembly assembly = Assembly.LoadFile("程式集路徑,不能是相對路徑"); // 載入程式集(EXE 或 DLL)
object obj = assembly.CreateInstance("類的完全限定名(即包括名稱空間)"); // 建立類的例項 

2.2、若要反射當前專案中的類可以為:

Assembly assembly = Assembly.GetExecutingAssembly(); // 獲取當前程式集
object obj = assembly.CreateInstance("類的完全限定名(即包括名稱空間)"); // 建立類的例項,返回為 object 型別,需要強制型別轉換

2.3、也可以為:

Type type = Type.GetType("類的完全限定名");
object obj = type.Assembly.CreateInstance(type);

=======================================================
補充:
1)反射建立某個類的例項時,必須保證使用類的完全限定名(名稱空間 + 類名)。Type.GetType 方法返回 null 則意味搜尋元資料中的相關資訊失敗(反射失敗),請確保反射時使用類的完全限定名。
2)反射功能十分強大,沒有什麼不能實現的。若實現“跨程式集”,請使用第一種方法建立類的例項,並反射該例項的欄位、屬性、方法、事件... 然後動態呼叫之。