• 當前位置:首頁 > IT技術 > Windows編程 > 正文

    C#中的反射
    2021-08-07 23:39:58

    一:什么是反射

    C#編寫的程序會編譯成一個程序集(.DLL或.exe),其中會包含元數據、編譯代碼和資源,通過反射可以獲取到程序集中的信息
    通俗來講,反射就是我們在只知道一個對象的外部而不了解內部結構的情況下,可以知道這個對象的內部實現


    二:反射的優缺點

    首先在編譯中分為動態編譯和靜態編譯,靜態編譯是在編譯中確定類型,綁定對象,而動態編譯是在運行中確定類型,綁定對象
    反射的優點就是可以動態創建對象、綁定對象,提高了程序的靈活性和擴展性,但反射是一種解釋操作,在性能上不如靜態編譯快


    三:通過Type類獲取程序集、模塊、類的相關信息

    ——Type類是一個抽象類,因此不能用他去實例化對象
    ——object類中定義了一個GetType方法,因此所有類都可以使用GetType()獲取到某一個對象所屬類的Type對象
    ——通過Type對象可以獲取到類中字段、屬性、方法、構造函數等信息

    using System;
    
    class MainClass
    {
        public static void Main(string[] args)
        {
            //1.通過對象獲取到這個對象所屬類的Type對象
            TestClass c = new TestClass();
            Type t = c.GetType();
    
            //2.通過Type類中的靜態方法GetType獲取到類的Type對象
            //Type t = Type.GetType("TestClass");
    
            //3.通過typeof關鍵字獲取到類的Type對象
            //Type t = typeof(TestClass);
    
            Console.WriteLine(t.Name);//獲取類名(不帶命名空間)
            Console.WriteLine(t.FullName);//獲取類名(帶命名空間)
            Console.WriteLine(t.Assembly);//獲取程序集
            Console.WriteLine(t.BaseType);//獲取基類類型
    
            Console.WriteLine("----------獲取類中字段");
            var fields = t.GetFields();
            foreach (var temp in fields)
            {
                Console.WriteLine(temp.Name);
            }
    
            Console.WriteLine("----------獲取類中屬性");
            var properties = t.GetProperties();
            foreach (var temp in properties)
            {
                Console.WriteLine(temp.Name);
            }
    
            Console.WriteLine("----------獲取類中方法");
            var methods = t.GetMethods();
            foreach (var temp in methods)
            {
                Console.WriteLine(temp.Name);
            }
    
            Console.WriteLine("----------獲取類中成員");
            var members = t.GetMembers();
            foreach (var temp in members)
            {
                Console.WriteLine(temp.Name);
            }
    
            Console.WriteLine("----------獲取類中嵌套類");
            var nesteds = t.GetNestedTypes();
            foreach (var temp in nesteds)
            {
                Console.WriteLine(temp.Name);
            }
    
            Console.WriteLine("----------獲取類中構造函數");
            var constructors = t.GetConstructors();
            foreach (var temp in constructors)
            {
                Console.WriteLine(temp.Name);
            }
        }
    }
    
    public class TestClass
    {
        public string str;
        public int num { get; set; }
        public void Fun()
        {
    
        }
        public class TestNestedClass
        {
    
        }
    }

    得到一個Type類型對象有三種方法:object.GetType()、Type.GetType()、typeof()
    使用object.GetType()必須先創建一個實例,而后兩種不需要創建實例,但使用typeof運算符仍然需要知道類型的編譯時信息,Type.GetType()靜態方法不需要知道類型的編譯時信息,所以是首選方法


    四:創建實例:性能上要比new差

    ——通過Activator創建實例

    using System;
    
    class MainClass
    {
        public static void Main(string[] args)
        {
            object c = Activator.CreateInstance(typeof(TestClass), "hello world");
            Console.WriteLine(((TestClass)c).str);
        }
    }
    
    public class TestClass
    {
        public string str;
        public TestClass(string str)
        {
            this.str = str;
        }
    }

    ?

    ?

    ——通過構造函數創建實例

    using System;
    
    class MainClass
    {
        public static void Main(string[] args)
        {
            Type t = typeof(TestClass);
            Type[] paramTypes = new Type[1] { typeof(string) };
            var info = t.GetConstructor(paramTypes);
            object[] param = new object[1] { "hello world" };
            var o = info.Invoke(param);
    
            Console.WriteLine(((TestClass)o).str);
        }
    }
    
    public class TestClass
    {
        public string str;
        public TestClass(string str)
        {
            this.str = str;
        }
    }

    五:反射賦值

    using System;
    using System.Reflection;
    
    class MainClass
    {
        public static void Main(string[] args)
        {
            TestClass cc = new TestClass();
            Type t = cc.GetType();
            FieldInfo info = t.GetField("str");
            info.SetValue(cc, "hello world");
            Console.WriteLine(info.GetValue(cc)); 
        }
    }
    
    public class TestClass
    {
        public string str;
    }

    ?

    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码