【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");

 

posted @ 2021-11-01 14:35  小林野夫  阅读(1383)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/