二、反射(Reflection)
1、反射:就是一个微软提供的帮助类库,可以解析并使用元数据。
2、exe/dll----ILSpy工具打开会包含matedata(元数据),描述了当前程序集中有哪些元素成员
3、反射动态加载dll文件,调用方法
{
//1、引用,2、new,3、调方法
IDBHelper helper = new SqlServerHelper();
helper.Query();
}
{
//反射方式:
//1、动态加载dll文件
Assembly assembly1 = Assembly.Load("Business.DB.SqlServer");//带上dll名称,在当前执行目录下找
Assembly assembly2 = Assembly.LoadFrom("Business.DB.SqlServer.dll");//带上.dll后缀名,在当前执行目录下找
Assembly assembly3 = Assembly.LoadFile("D:\\GIT\\Advanced\\Advanced" +
"\\MyReflection\\Business.DB.SqlServer.dll");//带上全路径
//2、获取类型名称
Type type = assembly1.GetType("Business.DB.SqlServer.SqlServerHelper");
//3、使用反射创建对象
object? oInstance = Activator.CreateInstance(type);
//4、类型转换
IDBHelper helper = oInstance as IDBHelper;
//5、调用方法
helper.Query();
dynamic oInstance1 = Activator.CreateInstance(type);
oInstance1.Query();
oInstance1.fasdfdsfqwe123412();//不存在的方法也可以写,不严谨的
//在不知道dll档中有什么内容可以这样获取所有的
//foreach (var type in assembly1.GetTypes())
//{
// Console.WriteLine($"Type.Name={type.Name}");
// foreach (var item in type.GetMethods())
// {
// Console.WriteLine($"Method.Name={item.Name}");
// }
// foreach (var item in type.GetProperties())
// {
// Console.WriteLine($"Property.Name={item.Name}");
// }
// foreach (var item in type.GetProperties())
// {
// Console.WriteLine($"Property.Name={item.Name}");
// }
//}
}
4、反射+配置文件+简单工厂---实现程序的可配置化
应用:比如动态更新dll版本,比如数据库从SqlServer切换到Mysql
using Business.DB.Interface;
using Microsoft.Extensions.Configuration;
using System;
using System.Reflection;
namespace MyReflecttion
{
public class SimpleFactory
{
/// <summary>
/// 提供一个返回IDBHelper的方法
/// 1、完全断开了对于普通类的依赖
/// 2、配置文件的修改,不需要停止项目运行
/// 3、反射+配置文件+简单工厂===程序的可配置化, 可以扩展化~
/// </summary>
/// <returns></returns>
public static IDBHelper CreateInstance()
{
string ReflictionConfig = CustomConfigManager.GetConfig("ReflictionConfig");
string[] strings= ReflictionConfig.Split(',');
string dllName = strings[1];
string typeName = strings[0];
Assembly assembly = Assembly.LoadFrom(dllName);
Type type = assembly.GetType(typeName);
object? oInstance = Activator.CreateInstance(type);
IDBHelper dBHelper = oInstance as IDBHelper;
return dBHelper;
}
}
public static class CustomConfigManager
{
//Core 读取配置文件:appsettings
//1.Microsoft.Extensions.Configuration;
//2.Microsoft.Extensions.Configuration.Json
public static string GetConfig(string key)
{
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json"); //默认读取 当前运行目录
IConfigurationRoot configuration = builder.Build();
string configValue = configuration.GetSection(key).Value;
return configValue;
}
}
}
5、反射黑科技:反射破坏单例,反射可以突破访问修饰符的权限(比如Private私有修饰,可以在类外部调用)
//定义一个单例,构造函数定义为私有的,在类的外部可以调用它。
namespace DB.SqlServer
{
public sealed class Singleton
{
private static Singleton _Singleton;
private Singleton()
{
Console.WriteLine("构造函数被调用");
}
static Singleton()
{
_Singleton = new Singleton();
}
public static Singleton GetInstance() { return _Singleton; }
}
}
6、反射调用方法+反射创建对象升级
1、获取要调用的方法名称
2、获取方法的类型,MethodInfo
3、Invoke方法,执行方法
{
//调用普通方法
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");
Type? type = assembly.GetType("DB.SqlServer.SqlServerHelper");
object? oInstance = Activator.CreateInstance(type);
MethodInfo query = type.GetMethod("Query");
query.Invoke(oInstance, new object[0]);
}
{
//在反射创建对象的时候,如何指定执行多个构造函数中的某个?
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");
Type? type = assembly.GetType("DB.SqlServer.ReflectionTest");
//如果要选择构造函数,在调用方法的时候,直接传入和参数列表匹配的参数即可
object? oInstance = Activator.CreateInstance(type);
object? oInstance1 = Activator.CreateInstance(type,new object[] {"你好" });
object? oInstance2 = Activator.CreateInstance(type,new object[] { 1233});
object? oInstance3 = Activator.CreateInstance(type,new object[] { "你好",123});
object? oInstance4 = Activator.CreateInstance(type,new object[] { 123,"你好不好"});
}
{
//执行各种方法
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");
Type? type = assembly.GetType("DB.SqlServer.SqlServerHelper");
object? oInstance = Activator.CreateInstance(type);
//执行Show1 --无参方法
MethodInfo query = type.GetMethod("Show1");
query.Invoke(oInstance, null);
//执行Show2 --带参方法
MethodInfo query2 = type.GetMethod("Show2");
query.Invoke(oInstance, [3456]);//传入的参数类型要和方法的参数完全匹配
//执行Show3 --重载方法
//对于重载方法,需要进一步精确查找的是哪个方法
MethodInfo query3 = type.GetMethod("Show3",new Type[] { typeof(int),typeof(string)});
query.Invoke(oInstance, new object[] { 123412,"你好我不好"});
//执行Show4 --私有方法
MethodInfo query4 = type.GetMethod("Show4", BindingFlags.Instance | BindingFlags.NonPublic);
query4.Invoke(oInstance, new object[] { "你好我不好" });
//执行Show5 --静态方法
MethodInfo query5 = type.GetMethod("Show4");
query5.Invoke(null, new object[] { "你好我不好" });//静态类不需要类的实例就可以执行
}
//测试类如下
namespace DB.SqlServer
{
/// <summary>
/// 反射测试类
/// </summary>
public class ReflectionTest
{
#region Identity
/// <summary>
/// 无参构造函数
/// </summary>
public ReflectionTest()
{
Console.WriteLine($"这里是{GetType()}无参数构造函数");
}
/// <summary>
/// 带参数构造函数
/// </summary>
/// <param name="name"></param>
public ReflectionTest(string name)
{
Console.WriteLine($"这里是{GetType()} 有参数构造函数");
}
public ReflectionTest(int id)
{
Console.WriteLine($"这里是{GetType()} 有参数构造函数");
}
public ReflectionTest(int id, string name)
{
//typeof(int);
//Type //id.GetType();
Console.WriteLine($"这里是{GetType()} 有参数构造函数");
}
public ReflectionTest(string name, int id)
{
//typeof(int);
//Type //id.GetType();
Console.WriteLine($"这里是{GetType()} 有参数构造函数");
}
#endregion
#region Method
/// <summary>
/// 无参方法
/// </summary>
public void Show1()
{
Console.WriteLine($"这里是{GetType()}的Show1");
}
/// <summary>
/// 有参数方法
/// </summary>
/// <param name="id"></param>
public void Show2(int id)
{
Console.WriteLine($"这里是{GetType()}的Show2");
}
/// <summary>
/// 重载方法之一
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
public void Show3(int id, string name)
{
Console.WriteLine($"这里是{GetType()}的Show3");
}
/// <summary>
/// 重载方法之二
/// </summary>
/// <param name="name"></param>
/// <param name="id"></param>
public void Show3(string name, int id)
{
Console.WriteLine($"这里是{GetType()}的Show3_2");
}
/// <summary>
/// 重载方法之三
/// </summary>
/// <param name="id"></param>
public void Show3(int id)
{
Console.WriteLine($"这里是{GetType()}的Show3_3");
}
/// <summary>
/// 重载方法之四
/// </summary>
/// <param name="name"></param>
public void Show3(string name)
{
Console.WriteLine("这里是{this.GetType()}的Show3_4");
}
/// <summary>
/// 重载方法之五
/// </summary>
public void Show3()
{
Console.WriteLine($"这里是{GetType()}的Show3_1");
}
/// <summary>
/// 私有方法
/// </summary>
/// <param name="name"></param>
private void Show4(string name) //肯定是可以的
{
Console.WriteLine($"这里是{GetType()}的Show4");
}
/// <summary>
/// 静态方法
/// </summary>
/// <param name="name"></param>
public static void Show5(string name)
{
Console.WriteLine($"这里是{typeof(ReflectionTest)}的Show5");
}
#endregion
}
}
7、泛型类、泛型方法调用
{
//普通类的泛型方法调用
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");
Type type = assembly.GetType("DB.SqlServer.GenericMethod");
object? oInstance = Activator.CreateInstance(type);
MethodInfo show = type.GetMethod("Show");
MethodInfo generic = show.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
generic.Invoke(oInstance,new object[] { 123,"1234",DateTime.Now});
}
{
//泛型类的普通方法调用
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");
Type type = assembly.GetType("DB.SqlServer.GenericClass`3");
Type typeG = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
object? oInstance = Activator.CreateInstance(typeG);
MethodInfo show = typeG.GetMethod("Show");
show.Invoke(oInstance, new object[] { 123, "1234", DateTime.Now });
}
{
//泛型类的泛型方法调用
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");
Type type = assembly.GetType("DB.SqlServer.GenericDouble`1");
Type typeG = type.MakeGenericType(new Type[] { typeof(int) });
object? oInstance = Activator.CreateInstance(typeG);
MethodInfo show = typeG.GetMethod("Show");
MethodInfo generic = show.MakeGenericMethod(new Type[] { typeof(string), typeof(DateTime) });
generic.Invoke(oInstance, new object[] { 123, "1234", DateTime.Now });
}
//测试类如下
namespace DB.SqlServer
{
public class GenericMethod
{
public void Show<T, W, X>(T t, W w, X x)
{
Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type={x.GetType().Name}");
Console.WriteLine($"T={t},W={w},X={x}");
}
}
public class GenericClass<T, W, X>
{
public void Show(T t, W w, X x)
{
Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type={x.GetType().Name}");
}
}
public class GenericDouble<T>
{
public void Show<W, X>(T t, W w, X x)
{
Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type={x.GetType().Name}");
}
}
}
8、反射的局限性---性能问题
反射方式比普通方式的耗时,高一倍以上。
反射不否认他有性能损失,但是只要程序员足够优秀,性能是可以得到优化的,可以放心使用
using DB.Interface;
using DB.SqlServer;
using System.Diagnostics;
using System.Reflection;
namespace MyReflection
{
public class Monitor
{
public static void Show()
{
Console.WriteLine("*******************Monitor*******************");
long commonTime = 0;
long reflectionTime = 0;
{
Stopwatch watch = new Stopwatch();
watch.Start();
for (int i = 0; i < 1000_000; i++) //1000000000
{
IDBHelper iDBHelper = new SqlServerHelper();
iDBHelper.Query();
}
watch.Stop();
commonTime = watch.ElapsedMilliseconds;
}
{
Stopwatch watch = new Stopwatch();
watch.Start();
Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");//1 动态加载
Type dbHelperType = assembly.GetType("DB.SqlServer.SqlServerHelper");//2 获取类型
for (int i = 0; i < 1000_000; i++)
{
//Assembly assembly = Assembly.LoadFrom("DB.SqlServer.dll");//1 动态加载
//Type dbHelperType = assembly.GetType("DB.SqlServer.SqlServerHelper");//2 获取类型
object oDBHelper = Activator.CreateInstance(dbHelperType);//3 创建对象
IDBHelper dbHelper = (IDBHelper)oDBHelper;//4 接口强制转换
dbHelper.Query();//5 方法调用
}
watch.Stop();
reflectionTime = watch.ElapsedMilliseconds;
}
Console.WriteLine($"commonTime={commonTime} reflectionTime={reflectionTime}");
}
}
}
9、反射调用字段属性
{
//反射调用字段属性
Type type = typeof(People);
object oInstance = Activator.CreateInstance(type);
//反射赋值
foreach (PropertyInfo prop in type.GetProperties())
{
if (prop.Name == "Id")
{
prop.SetValue(oInstance, 1234);
}
else if (prop.Name == "Name")
{
prop.SetValue(oInstance, "RoseLoves");
}
}
//反射取值
foreach (PropertyInfo prop in type.GetProperties())
{
Console.WriteLine($"{prop.Name} = {prop.GetValue(oInstance)}");
}
}
10、反射+ADO.NET 实现ORM框架
1、实现基本的查询功能
using DB.Interface;
using Microsoft.Data.SqlClient;
using System.Reflection;
namespace DB.SqlServer
{
public class SqlServerHelper : IDBHelper
{
private readonly string _ConnectionStr;
public SqlServerHelper(){ }
public SqlServerHelper(string connectionStr)
{
_ConnectionStr = connectionStr;
}
public void Query() { }
public List<T> GetCompany<T>(int id)
{
//1.准备数据库连接字符串
//_ConnectionStr
//2.创建连接对象
SqlConnection connection = new SqlConnection(_ConnectionStr);
connection.Open();//打开连接
//反射创建属性
List<T> list = new List<T>();
Type type = typeof(T);
object oInstance = Activator.CreateInstance(type);
//3.准备命令,Sql语句
//string sql = $"SELECT * FROM Company WHERE ID = '{id}'";
string sql = $"SELECT {string.Join(',', type.GetProperties().Select(c => c.Name).ToList())} FROM {type.Name} WHERE ID = {id}";
//4.准备命令执行对象
SqlCommand command = new SqlCommand(sql, connection);
//执行命令(执行sql语句)
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
//反射取值
foreach (PropertyInfo prop in type.GetProperties())
{
prop.SetValue(oInstance, reader[prop.Name] is DBNull ? null : reader[prop.Name]);
}
list.Add((T)oInstance);
}
return list;
}
}
}
{
//反射+AOD.NET 实现ORM框架
string constr = "Data Source=LAPTOP-FR93A6FM;Initial Catalog=CustomerDB;Persist Security Info=True;User ID=sa;Password=Xjc000000;Trust Server Certificate=True";
SqlServerHelper sqlServerHelper = new SqlServerHelper(constr);
var c = sqlServerHelper.GetCompany<Company>(13479);
Console.WriteLine(c[0].Name);
var S = sqlServerHelper.GetCompany<SysUser>(13479);
}
2、但是在上述操作中,SQL语句在每次执行都要创建一次,用反射创建对象会有性能损耗。所以可以用缓存
Sql语句的生成特点:
a、同类型的sql语句是一样的
b、同一类型的操作,sql语句只需要生成一次
c、如果要缓存,为每一个类型做一个缓存,也就是泛型缓存:泛型缓存的本质是泛型类。
namespace DB.SqlServer
{
public class SqlBuilder<T>
{
private static string _QuerySql;
/// <summary>
/// 使用静态构造函数初始化
/// </summary>
static SqlBuilder()
{
Type type = typeof(T);
_QuerySql = $"SELECT {string.Join(',', type.GetProperties().Select(c => c.Name).ToList())} FROM {type.Name} WHERE ID =";
}
public static string GetQuerySql(int id) => $"{_QuerySql} {id}";
}
}
using DB.Interface;
using DB.Models;
using Microsoft.Data.SqlClient;
using System.Reflection;
namespace DB.SqlServer
{
public class SqlServerHelper : IDBHelper
{
private readonly string _ConnectionStr;
public SqlServerHelper() { }
public SqlServerHelper(string connectionStr)
{
_ConnectionStr = connectionStr;
}
public void Query() { }
public List<T> GetCompany<T>(int id) where T : BaseModel//要求实体类必须有一个Id的字段
{
//1.准备数据库连接字符串
//_ConnectionStr
//2.创建连接对象
SqlConnection connection = new SqlConnection(_ConnectionStr);
connection.Open();//打开连接
//反射创建属性
List<T> list = new List<T>();
Type type = typeof(T);
object oInstance = Activator.CreateInstance(type);
//3.准备命令,Sql语句
//string sql = $"SELECT * FROM Company WHERE ID = '{id}'";
//string sql = $"SELECT {string.Join(',', type.GetProperties().Select(c => c.Name).ToList())} FROM {type.Name} WHERE ID = {id}";
string sql = SqlBuilder<T>.GetQuerySql(id);
//4.准备命令执行对象
SqlCommand command = new SqlCommand(sql, connection);
//执行命令(执行sql语句)
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
//反射取值
foreach (PropertyInfo prop in type.GetProperties())
{
prop.SetValue(oInstance, reader[prop.Name] is DBNull ? null : reader[prop.Name]);
}
list.Add((T)oInstance);
}
return list;
}
}
}
11、反射生成程序集
原始:程序是设计好的,然后通过运行时环境去驱动,去执行设计好的程序指令;
EMit:在程序运行的过程中,动态的生成一堆新的程序出来-------程序造程序。
在程序运行时,要能够动态的生成程序集、类、结构、变量、方法、属性、字段。。。。。。
程序集(dll/exe)--->moudle----->类------>方法、属性。。。。。他们是逐级的包含关系
using System.Reflection;
using System.Reflection.Emit;
namespace MyReflecttion
{
public class ReflectionEmit
{
//一般的,使用反射发出(reflection emit)可能会是这样子的步骤:
//步骤一、创建一个新的程序集(程序集是动态的存在于内存中或把它们保存到磁盘上)。
//步骤二、在程序集内部,创建一个模块(module)。
//步骤三、在模块内部,创建一个类型。
//步骤四、给类型添加属性和方法。
//步骤五、产生属性和方法内部的代码
//确切得说,当你使用Reflection.Emit类产生代码时,以上描述的是你实际中要遵循的过程。
public static void Show()
{
AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
//程序集建造者
AssemblyBuilder ab = AssemblyBuilder.DefineDynamicAssembly(aName,
AssemblyBuilderAccess.RunAndCollect);
// 对于单个模块程序集,模块名称通常为
//程序集名称加上扩展名。
ModuleBuilder mb = ab.DefineDynamicModule("MyModal");
//基于module 配置要生成的类型
TypeBuilder tb = mb.DefineType("MyDynamicType", TypeAttributes.Public);
// 添加int(Int32)类型的私有字段。
FieldBuilder fbNumber = tb.DefineField("m_number",
typeof(int), FieldAttributes.Private);
// 定义一个接受一个int类型参数的构造函数
// 储存在私人区域。
Type[] parameterTypes = { typeof(int) };
ConstructorBuilder ctor1 = tb.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
parameterTypes);
ILGenerator ctor1IL = ctor1.GetILGenerator();
//对于构造函数,参数0是对新
//实例。在调用base之前将其推到堆栈上
//类构造函数。指定的默认构造函数
//通过传递
//类型(Type.EmptyTypes)到GetConstructor。
ctor1IL.Emit(OpCodes.Ldarg_0);
ctor1IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
//在推送参数之前,先将实例推送到堆栈上
//将被分配给私有字段m\u编号。
ctor1IL.Emit(OpCodes.Ldarg_0);
ctor1IL.Emit(OpCodes.Ldarg_1);
ctor1IL.Emit(OpCodes.Stfld, fbNumber);
ctor1IL.Emit(OpCodes.Ret);
//定义无参数构造函数
//定义提供默认值的默认构造函数
//私人领域。对于参数类型,传递空
//类型数组或传递null。
ConstructorBuilder ctor0 = tb.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes);
ILGenerator ctor0IL = ctor0.GetILGenerator();
//对于构造函数,参数0是对新
//实例。在推送默认值之前将其推送到堆栈上
//值,然后调用构造函数ctor1。
ctor0IL.Emit(OpCodes.Ldarg_0);
ctor0IL.Emit(OpCodes.Ldc_I4_S, 42);
ctor0IL.Emit(OpCodes.Call, ctor1);
ctor0IL.Emit(OpCodes.Ret);
//定义一个名为Number的属性,用于获取和设置私有 现场。
//DefineProperty的最后一个参数为null,因为属性没有参数(如果不指定null,则必须
//指定类型对象的数组。对于无参数属性,
//使用不带元素的内置数组:Type.EmptyTypes)
PropertyBuilder pbNumber = tb.DefineProperty(
"Number",
PropertyAttributes.HasDefault,
typeof(int),
null);
//属性“set”和属性“get”方法需要特殊的属性集。
MethodAttributes getSetAttr = MethodAttributes.Public |
MethodAttributes.SpecialName | MethodAttributes.HideBySig;
//为Number定义“get”访问器方法。方法返回
//一个整数,没有参数(注意null可以是
//代替类型使用。空类型)
MethodBuilder mbNumberGetAccessor = tb.DefineMethod("get_Number",
getSetAttr, typeof(int), Type.EmptyTypes);
ILGenerator numberGetIL = mbNumberGetAccessor.GetILGenerator();
//对于实例属性,参数0是实例。加载
//实例,然后加载private字段并返回
//堆栈上的字段值。
numberGetIL.Emit(OpCodes.Ldarg_0);
numberGetIL.Emit(OpCodes.Ldfld, fbNumber);
numberGetIL.Emit(OpCodes.Ret);
// 为Number定义“set”访问器方法,该方法没有返回值
//类型并接受一个int(Int32)类型的参数。
MethodBuilder mbNumberSetAccessor = tb.DefineMethod(
"set_Number",
getSetAttr,
null,
new Type[] { typeof(int) });
ILGenerator numberSetIL = mbNumberSetAccessor.GetILGenerator();
// 加载实例和数值参数,然后存储
numberSetIL.Emit(OpCodes.Ldarg_0);
numberSetIL.Emit(OpCodes.Ldarg_1);
numberSetIL.Emit(OpCodes.Stfld, fbNumber);
numberSetIL.Emit(OpCodes.Ret);
//最后,将“get”和“set”访问器方法映射到
//属性生成器。该属性现在已完成。
pbNumber.SetGetMethod(mbNumberGetAccessor);
pbNumber.SetSetMethod(mbNumberSetAccessor);
// 定义一个接受整数参数并返回
//该整数与专用字段mèu数的乘积。这个
//同时,参数类型的数组是动态创建的。
MethodBuilder meth = tb.DefineMethod(
"MyMethod",
MethodAttributes.Public,
typeof(int),
new Type[] { typeof(int) });
ILGenerator methIL = meth.GetILGenerator();
// 要检索private instance字段,请将实例加载到它
// 属于(参数0)。加载字段后,加载
// 参数一,然后乘。从方法返回
// 上的返回值(两个数字的乘积) 执行堆栈。
methIL.Emit(OpCodes.Ldarg_0);
methIL.Emit(OpCodes.Ldfld, fbNumber);
methIL.Emit(OpCodes.Ldarg_1);
methIL.Emit(OpCodes.Mul);
methIL.Emit(OpCodes.Ret);
// 完成类型
Type t = tb.CreateType();
// 下一行保存单个模块部件。这个
//需要AssemblyBuilderAccess包含Save。你现在可以了
//在命令提示符下键入“ildasm MyDynamicAsm.dll”,然后
// 检查组件。你也可以写一个程序
//对程序集的引用,并使用MyDynamicType类型。
//ab.bu(aName.Name + ".dll");
//由于AssemblyBuilderAccess包含Run,因此可以
//立即执行。从获取反射对象开始
//方法和属性。
MethodInfo mi = t.GetMethod("MyMethod");
PropertyInfo pi = t.GetProperty("Number");
// 使用默认值创建MyDynamicType的实例 建造师。
object o1 = Activator.CreateInstance(t);
// 显示属性的值,然后将其更改为127并
//再次显示。使用null表示属性
//没有索引。
Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));
pi.SetValue(o1, 127, null);
Console.WriteLine("o1.Number: {0}", pi.GetValue(o1, null));
// 调用MyMethod,传递22,并显示返回值22
// 乘以127。参数必须作为数组传递,即使
// 只有一个。
object[] arguments = { 22 };
Console.WriteLine("o1.MyMethod(22): {0}",
mi.Invoke(o1, arguments));
// 使用构造函数创建MyDynamicType的实例
//它指定了m\ U编号。构造函数由
//匹配参数数组中的类型。在这种情况下,
// 参数数组是动态创建的。显示
//属性值。
object o2 = Activator.CreateInstance(t,
new object[] { 5280 });
Console.WriteLine("o2.Number: {0}", pi.GetValue(o2, null));
}
}
}
标签:进阶,C#,Type,GetType,语法,new,type,public,string
From: https://www.cnblogs.com/SevenDouble/p/18647473