2018年7月5日 星期四

[C#] C#反射(Type、PropertyInfo、MethodInfo)的基本應用

System.Activator.CreateInstance(Type):建立類別的執行個體

sizeof(類型):用來取得類型的Type物件。

Object.GetType():用來取得物件的Type物件。

Convert.ChangeType(object, Type):傳回指定之類型的物件,此物件的值與指定的物件相等。


Type:代表類型宣告:類別類型、介面類型、陣列類型、值類型、列舉類型、類型參數、泛型類型定義,以及開放式或封閉式的建構泛型類型。

Type.BaseType:取得目前Type所直接繼承的類型。

Type.Name:取得目前類型的名稱。

Type.FullName:取得類型的完整名稱 (包括其命名空間,但不包括其組件)。

Type.IsAbstract:指出類型是否為抽象並且必須被覆寫。

Type.IsArray:指出類型是否為陣列。

Type.IsClass:指出類型是類別或委派。

Type.IsEnum:指出類型是否表示列舉類型。

Type.IsGenericType:指出類型是否為泛型類型。

Type.IsInterface:指出類型是否為介面。

Type.IsNotPublic:指出類型是否未宣告為公用。

Type.IsPublic:指出類型是否宣告為公用。

GetProperties():傳回類型的所有公用屬性。

GetProperty(String):搜尋具有指定名稱和傳回類型的公用屬性。

GetMethods():搜尋具有指定名稱的公用方法。

GetMethod(String):傳回類型的所有公用方法。


PropertyInfo:探索屬性的屬性,並提供屬性中繼資料的存取。

PropertyInfo.Name:取得屬性的名稱。

PropertyInfo.PropertyType:得此屬性的型別。

PropertyInfo.CanRead:是否可讀取屬性。

PropertyInfo.CanWrite:是否可寫入屬性。

PropertyInfo.GetValue(物件實體):傳回指定的物件的屬性值。

PropertyInfo.SetValue(物件實體, 屬性值):設定指定之物件的屬性值。


MethodInfo:探索方法的屬性並提供方法中繼資料 的存取。

MethodInfo.IsAbstract:指出方法是否為抽象。

MethodInfo.IsConstructor:指出方法是否為建構函式。

MethodInfo.IsFinal:指出這個方法是否為final。

MethodInfo.IsGenericMethod:指出方法是否為泛型。

MethodInfo.IsPrivate:指出方法是否為private。

MethodInfo.IsPublic:指出方法是否為public。

MethodInfo.IsStatic:指出方法是否為static。

MethodInfo.IsVirtual:指出方法是否為virtual。

MethodInfo.Name:取得此方法的名稱。

MethodInfo.Invoke(物件實體, 參數陣列)使用指定的參數叫用由目前執行個體代表的方法或建構函式。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace TestType
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Student student = new Student();
            student.SN = 1;
            student.ID = "S123456";
            student.Name = "Mike";
            student.Sex = true;
            student.Birthday = DateTime.Now;

            Room room = new Room();
            room.ID = "R001";
            room.Title = "會議室";
            room.Size = 10;
            room.Maneger = student;

            //存取所有Public屬性名稱及屬性值
            Console.WriteLine(GetData(student));
            Console.WriteLine();
            Console.WriteLine(GetData(room));

            //執行物件的Show方法
            ExecMethod(student, "Show");
            ExecMethod(room, "Show");

            //存取物件屬性-不會自動轉型
            SetValue(room, "Size", 20);
            Console.WriteLine(GetValue(room, "Size"));

            //存取物件屬性-會自動轉型
            SetValuePlus(room, "Size", "50");
            Console.WriteLine(GetValue(room, "Size"));

            //建立類別的執行個體。
            var manager = Activator.CreateInstance(typeof(Student));

            //存取物件屬性
            SetValuePlus(room, "Maneger", manager);
            Console.WriteLine(GetValue(room, "Maneger"));

            //存取物件屬性,設為null
            SetValuePlus(room, "Maneger", null);
            Console.WriteLine(GetValue(room, "Maneger"));

            Console.ReadKey();
        }

        //使用Type存取所有Public屬性名稱及屬性值
        public static string GetData(object obj)
        {
            Type type = obj.GetType();
            var properties = type.GetProperties();
            StringBuilder sr = new StringBuilder();
            foreach (var property in properties)
            {
                sr.Append(property.Name);
                sr.Append("=");
                sr.AppendLine(property.GetValue(obj).ToString());
            }

            return sr.ToString();
        }

        //使用Type執行物件方法
        public static void ExecMethod(object obj, string methodName)
        {
            Type type = obj.GetType();
            var method = type.GetMethod(methodName);
            if (method != null)
            {
                method.Invoke(obj, null);
            }
        }

        //使用Type設定屬性值
        public static void SetValue(object obj, string propertyName, object value)
        {
            Type type = obj.GetType();
            var property = type.GetProperty(propertyName);
            if (property != null)
            {
                property.SetValue(obj, value);
            }
        }

        //使用Type設定屬性值(會自動轉型)
        public static void SetValuePlus(object obj, string propertyName, object value)
        {
            Type type = obj.GetType();
            var property = type.GetProperty(propertyName);
            if (property != null)
            {
                property.SetValue(obj, (value == null) ? null : Convert.ChangeType(value, property.PropertyType));
            }
        }

        //使用Type取得屬性值(允許賦予null)
        public static object GetValue(object obj, string propertyName)
        {
            Type type = obj.GetType();
            var property = type.GetProperty(propertyName);
            if (property != null)
            {
                return property.GetValue(obj);
            }
            else
            {
                return null;
            }
        }
    }

    public class Student
    {
        public int SN { get; set; }

        public string ID { get; set; }

        public string Name { get; set; }

        public bool Sex { get; set; }

        public DateTime Birthday { get; set; }

        public void Show()
        {
            Console.WriteLine("Class type is Student.");
        }
    }

    public class Room
    {
        public string ID { get; set; }

        public string Title { get; set; }

        public int Size { get; set; }

        public Student Maneger { get; set; }

        public void Show()
        {
            Console.WriteLine("Class type is Room.");
        }

    }
}

沒有留言:

張貼留言