正文
反射 type 的基本用法,动态加载插件
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
这里介绍反射的简单实用
MyClass类
public class MyClass
{
public int Age { get; set; }
public string Name { get; set; } public MyClass()
{
Console.WriteLine("无参数的构造函数");
} public MyClass(string name)
{
this.Name = name;
Console.WriteLine("有参数的构造函数");
} public string GetUpperString(string str)
{
return str.ToUpper();
} private void PrivateMethod()
{
Console.WriteLine("PrivateMethod");
}
}
Type typeof
class Program
{
static void Main(string[] args)
{
Type typeMyClass = typeof(MyClass); //获取方法
MethodInfo methodinfo = typeMyClass.GetMethod("GetUpperString");
object result = methodinfo.Invoke(Activator.CreateInstance(typeMyClass), new object[] { "namesss to upper" });
Console.WriteLine(result);//NAMESSS TO UPPER //调用有参数的构造函数
ConstructorInfo ctorInfo = typeMyClass.GetConstructor(new Type[] { typeof(string) });
//ctorResult 是MyClass 对象
object ctorResult = ctorInfo.Invoke(new object[] { "namess" });
Console.WriteLine(ctorResult);//反射3.Myclass //获得 属性
PropertyInfo pInfo = typeMyClass.GetProperty("Name");
object names = pInfo.GetValue(Activator.CreateInstance(typeMyClass));
Console.WriteLine(names); PropertyInfo[] pinfos = typeMyClass.GetProperties(); Console.Read();
}
}
动态加载程序集
Assembly assembly = Assembly.LoadFile("");
Type[] types = assembly.GetTypes();
///获得指定的类型
Type type = assembly.GetType("空间名.类名"); //这里是找方法名是MethodName,私有的 或者静态的方法
MethodInfo minfo= typeMyClass.GetMethod("MethodName", BindingFlags.NonPublic | BindingFlags.Static);
2.反射还有一个作用,动态加载插件
要实现插件功能,首先 原程序要有一个接口,来规范插件
插件的接口IMyNoteExeInfer dll代码是
namespace MyNotePadExeInfer
{
/// <summary>
/// 接口默认不是public
/// </summary>
public interface IMyNoteExeInfer
{ /// <summary>
/// 插件的名称
/// </summary>
string name
{
get;
set;
}
/// <summary>
/// 运行插件
/// </summary>
/// <param name="txt">textbox的插件</param>
void Run(TextBox txt);
}
}
接着是 原程序要根据接口,动态加载(未来未知的)插件
private void Form1_Load(object sender, EventArgs e)
{
//加载插件
//1. 找到多个控件的文件路径
Assembly ass = Assembly.GetExecutingAssembly();
///规定好把插件放到执行目录的 addnotedll文件夹中
string pathfile = Path.Combine(Path.GetDirectoryName(ass.Location), "addnotedll");
//找到每个插件的绝对路径
string[] filePaths = Directory.GetFiles(pathfile, "*.dll");
foreach (string fileP in filePaths)
{
Assembly oneAssmebly = Assembly.LoadFrom(fileP);
Type[] types = oneAssmebly.GetExportedTypes();//获得程序集中的public 类型
//规范插件的接口IMyNoteExeInfer
Type typeNoteInfer = typeof(IMyNoteExeInfer);
for (int i = ; i < types.Length; i++)
{
//挑取实现了接口IMyNoteExeInfer的类型
if (typeNoteInfer.IsAssignableFrom(types[i]) && !types[i].IsAbstract)
{
//创建当前类型的实例
IMyNoteExeInfer currDllInstance = (IMyNoteExeInfer)Activator.CreateInstance(types[i]); //在工具下拉单toolSmiSet中 加入控件
ToolStripItem newAdditem= toolSmiSet.DropDownItems.Add(currDllInstance.name);
newAdditem.Tag = currDllInstance;//把插件对象传过去,这样在那里就可以用对象调方法了
//给新增加的下拉单 注册单击事件
newAdditem.Click +=newAdditem_Click;
}
} } } private void newAdditem_Click(object sender, EventArgs e)
{
//sender就是单击的下拉单
ToolStripItem newitem = (ToolStripItem)sender;
//newitem.Tag传过来的是对象 插件的对象
//因为插件对象都继承接口,所以可以直接用接口接受
IMyNoteExeInfer iexeInfer= (IMyNoteExeInfer)newitem.Tag;
iexeInfer.Run(textBox1);//运行插件
}
下面是插件的dll代码
public class MyNoteToUpper : IMyNoteExeInfer
{
/// <summary>
/// 运行插件
/// </summary>
/// <param name="txt"></param>
public void Run(TextBox txt)
{
txt.Text = txt.Text.ToUpper(); }
private string _name;
/// <summary>
/// 插件的名字
/// </summary>
public string name
{
get { return "ToUpper"; }
set { _name = value; }
}
}