C#中的反射

一:什麼是反射

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


二:反射的優缺點

首先在編譯中分爲動態編譯和靜態編譯,靜態編譯是在編譯中肯定類型,綁定對象,而動態編譯是在運行中肯定類型,綁定對象
反射的優勢就是能夠動態建立對象、綁定對象,提升了程序的靈活性和擴展性,但反射是一種解釋操做,在性能上不如靜態編譯快函數


三:經過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()靜態方法不須要知道類型的編譯時信息,因此是首選方法this


四:建立實例:性能上要比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;
}
相關文章
相關標籤/搜索