【C#反射】Type的用法


Type屬性的應用

 

Type type = typeof(MyClass);
Console.Write("$類型名:{ type.Name}");
Console.Write("$類全名:{type.FullName}" );
Console.Write("$命名空間名:{ype.Namespace}");
Console.Write("$程序集名:{type.Assembly}" );
Console.Write("$模塊名:{type.Module}" );
Console.Write("$基類名:{type.BaseType}" ); //C# 中,一個類型只能繼承一個類型(基類型),使用實例的 Type.BaseType 屬性,可以獲取到此類型的基類型。
Console.Write("$是否類:{type.IsClass}");
Console.Write("$類的公共成員:{}");
MemberInfo[] memberInfos = type.GetMembers();//得到所有公共成員
foreach (var item in memberInfos)
{
   Console.Write(string.Format("${ item.MemberType}:{ item}"));
                
}

 

Type.MakeGenericType 動態創建泛型

// 先創建開放泛型
Type openType = typeof(List<>);
// 再創建具象泛型
Type target = openType.MakeGenericType(new[] { typeof(string) });
// 最后創建泛型實例
List<string> result = (List<string>)Activator.CreateInstance(target);

 

 

c# Type.InvokeMember用法

 public object InvokeMember(string, BindingFlags, Binder, object, object[]);
string:你所要調用的函數名
BindingFlags:你所要調用的函數的屬性,可以組合
Binder:實例
object:調用該成員函數的實例
object[]:參數,
下面是msdn例子:

 

 class MyType
    {
        Int32 myField;
        public MyType(ref Int32 x) { x *= 5; }
        public override String ToString() { return myField.ToString(); }
        public Int32 MyProp
        {
            get { return myField; }
            set
            {
                if (value < 1)
                    throw new ArgumentOutOfRangeException("value", value, "value must be > 0");
                myField = value;
            }
        }
    }

    class MyApp
    {
        static void Main()
        {
            Type t = typeof(MyType);
            // Create an instance of a type.
            Object[] args = new Object[] { 8 };
            int ss = 5;
            Console.WriteLine("The value of x before the constructor is called is {0}.", args[0]);
            Object obj =(object) new MyType(ref ss);
            //也可以這樣寫 Object obj =t.InvokeMember(null,BindingFlags.CreateInstance, null, null, args);
            Console.WriteLine("Type: " + obj.GetType().ToString());
            Console.WriteLine("The value of x after the constructor returns is {0}.", args[0]);

            // Read and write to a field.
            t.InvokeMember("myField",BindingFlags.Instance|BindingFlags.NonPublic| BindingFlags.SetField, null, obj, new Object[] { 5 });
            Int32 v = (Int32)t.InvokeMember("myField",BindingFlags.NonPublic |BindingFlags.Instance | BindingFlags.GetField, null, obj, null);
            Console.WriteLine("myField: " + v);

            // Call a method.
            String s = (String)t.InvokeMember("ToString",BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null, obj, null);
            Console.WriteLine("ToString: " + s);

            // Read and write a property. First, attempt to assign an
            // invalid value; then assign a valid value; finally, get
            // the value.
            try
            {
                // Assign the value zero to MyProp. The Property Set
                // throws an exception, because zero is an invalid value.
                // InvokeMember catches the exception, and throws
                // TargetInvocationException. To discover the real cause
                // you must catch TargetInvocationException and examine
                // the inner exception.
                t.InvokeMember("MyProp",
                    BindingFlags.DeclaredOnly |
                    BindingFlags.Public | BindingFlags.NonPublic |
                    BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new Object[] { 0 });
            }
            catch (TargetInvocationException e)
            {
                // If the property assignment failed for some unexpected
                // reason, rethrow the TargetInvocationException.
                if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException))
                    throw;
                Console.WriteLine("An invalid value was assigned to MyProp.");
            }
            t.InvokeMember("MyProp",
                BindingFlags.DeclaredOnly |
                BindingFlags.Public |
                BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new Object[] { 2 });
            v = (Int32)t.InvokeMember("MyProp",
                BindingFlags.DeclaredOnly |
                BindingFlags.Public | BindingFlags.NonPublic |
                BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null);
            Console.WriteLine("MyProp: " + v);
        }
    }

 

 

 

 Type類 GETXXXX的方法

 

 

 

GetConstructor(), GetConstructors():返回ConstructorInfo類型,用於取得該類的構造函數的信息

GetEvent(), GetEvents():返回EventInfo類型,用於取得該類的事件的信息

GetField(), GetFields():返回FieldInfo類型,用於取得該類的字段(成員變量)的信息

GetInterface(), GetInterfaces():返回InterfaceInfo類型,用於取得該類實現的接口的信息

GetMember(), GetMembers():返回MemberInfo類型,用於取得該類的所有成員的信息

GetMethod(), GetMethods():返回MethodInfo類型,用於取得該類的方法的信息
 
GetProperty(), GetProperties():返回PropertyInfo類型,用於取得該類的屬性的信息
    可以調用這些成員,其方式是調用Type的InvokeMember()方法,或者調用MethodInfo, PropertyInfo和其他類的Invoke()方法。

 

。。。。。。。

 

4、使用示例代碼

 

1) 查看類中的構造方法

 

  NewClassw nc = new NewClassw();
  Type t = nc.GetType();
  ConstructorInfo[] ci = t.GetConstructors();    //獲取類的所有構造函數
  foreach (ConstructorInfo c in ci) //遍歷每一個構造函數
      {
         ParameterInfo[] ps = c.GetParameters();    //取出每個構造函數的所有參數
      
            foreach (ParameterInfo pi in ps)   //遍歷並打印所該構造函數的所有參數
            {
               Console.Write(pi.ParameterType.ToString() + " " + pi.Name + ",");
            }
         Console.WriteLine();
      }

 

2) 用構造函數動態創建對象

 

Type t = typeof(NewClassw);
     
Type[] pt = new Type[2];
     
pt[0] = typeof(string);
     
pt[1] = typeof(string);
        //根據參數類型獲取構造函數 
     
ConstructorInfo ci = t.GetConstructor(pt); 
   //構造Object數組,作為構造函數的輸入參數 
      
object[] obj = new object[2]{"grayworm","hi.baidu.com/grayworm"};   
        //調用構造函數生成對象 
      
object o = ci.Invoke(obj);    
    
//調用生成的對象的方法測試是否對象生成成功 
  
//((NewClassw)o).show();   

 

3) 用Activator創建對象

 

Type t = typeof(NewClassw);
    
//構造函數的參數 
        
object[] obj = new object[2] { "grayworm", "hi.baidu.com/grayworm" };   
      
//用Activator的CreateInstance靜態方法,生成新對象 
        object o = Activator.CreateInstance(t,"grayworm","hi.baidu.com/grayworm"); 
      
//((NewClassw)o).show();

 

4) 查看類中的屬性

 

NewClassw nc = new NewClassw();
        
Type t = nc.GetType();
        
PropertyInfo[] pis = t.GetProperties();
        
foreach(PropertyInfo pi in pis)
       
 {
            
     Console.WriteLine(pi.Name);
       
 }

 

5) 查看類中的public方法

 

NewClassw nc = new NewClassw();
        
Type t = nc.GetType();
        
MethodInfo[] mis = t.GetMethods();
        
foreach (MethodInfo mi in mis)
        
{
            
    Console.WriteLine(mi.ReturnType+" "+mi.Name);
        
}

 

6) 查看類中的public字段

 

NewClassw nc = new NewClassw();
        
Type t = nc.GetType();
        
FieldInfo[] fis = t.GetFields();
       
foreach (FieldInfo fi in fis)
        
{
            
    Console.WriteLine(fi.Name);
        
} 

 

7) 用反射生成對象,並調用屬性、方法和字段進行操作 

 

NewClassw nc = new NewClassw();
        
Type t = nc.GetType();
       
object obj = Activator.CreateInstance(t);
        
//取得ID字段         
FieldInfo fi = t.GetField("ID");
        
//給ID字段賦值         
fi.SetValue(obj, "k001");
        
//取得MyName屬性         
PropertyInfo pi1 = t.GetProperty("MyName");
        
//給MyName屬性賦值         
pi1.SetValue(obj, "grayworm", null);
       // null表示無參屬性,有參是索引,必須傳入一個實例,
PropertyInfo pi2 = t.GetProperty("MyInfo");
        
pi2.SetValue(obj, "hi.baidu.com/grayworm", null);
        
//取得show方法         
MethodInfo mi = t.GetMethod("show");
        
//調用show方法         
mi.Invoke(obj, null);


 

 

 

System.Type 創建實例

使用Type.InvokerMember可以調用類型的方法、屬性。自然也可以通過調用類型的構造函數來創建一個類型的實例。

//直接調用無參構造函數
Object obj = typeof(Employee).InvokeMember(null, BindingFlags.CreateInstance, null, null, null);//BindingFlags.CreateInstance會調用構造函數
Employee employee =obj as Employee;
employee.Say("InvokeMember default ctor");

// 使用帶參數的構造函數
obj = typeof(Employee).InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] { "david" });
employee = obj as Employee;
((Employee)obj).Say("InvokeMember ctor with argument");

 


免責聲明!

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



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