做一程序,老大说以后功能升级要用到程序集。于是学习使用反射和程序集,对其中一些心存疑惑。看了一些书和例子,小有感悟,小写与此,以备忘
先是参看了《C#精髓》上相关章节的内容,类型迟绑定的例子:(控制台程序实例)
1.建立一个类库,命名Greeting,编译为Greeting.dll
using System;
using System.Collections.Generic;
using System.Text;
namespace Greeting
{
public abstract class Class1
{
public abstract void SayHello();
}
}
2.建立类库English,引用Greeting.dll,继承Greeting里的类,重载Greeting内的虚方法;
using System;
using System.Collections.Generic;
using System.Text;
namespace English
{
public class AmericanGreeting : Greeting.Class1
{
private string msg = "Hey, dude, Wassup !";
public override void SayHello()
{
Console.WriteLine(msg);
}
}
public class BritishGreeting : Greeting.Class1
{
private string msg = "Good morning , old chap !";
public override void SayHello()
{
Console.WriteLine(msg);
}
}
}
3.主程序
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
namespace 反射实验
{
class Program
{
static void Main(string[] args)
{
foreach (string s in args)
{
Assembly a = Assembly.LoadFrom(s);
foreach (Type t in a.GetTypes())
if (t.IsSubclassOf(typeof(Greeting.Class1)))
{
object o = Activator.CreateInstance(t);
MethodInfo mi = t.GetMethod("SayHello");
mi.Invoke(o,null);
}
}
}
}
}
这样,即使程序已经发布,如果需要增加某个功能,不需要改动程序,新建一个类库比如Test,继承Greeting的类,在其内部实现需要的方法,在主程序(这里控制台运行时是靠参数传入的)运行时后跟该dll即可,当然,如果是实现了多个方法,需要在主程序代码处
MethodInfo mi = t.GetMethod("SayHello");
将"SayHello"方法改为新的方法名,这里也可以用编程的方法动态获得,以便增加灵活性
编译,运行,需要将English.dll拷贝到主程序目录下(或者运行时指定完整路径),比如本主程序编译后为 程序集.exe,则在控制台下运行:
程序集.exe English.dll
输出结果:Hey, dude, Wassup !
Good morning , old chap !
《C#精髓》内的原话:“这个例子有一点很有趣,它是完全的迟绑定,也就是说,在SayHello程序发布以后很长时间,你还可以创建一个新类型,让SayHello自动地使用它,只需在命令行中指定。这是通过反射的迟绑定的关键优点之一。”