创建一个接口类
创建一个动物Animal的接口,接口方法为Call,方法内容为让某个动物叫。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IReflectionApi { public interface Animal { /// <summary> /// 叫 /// </summary> /// <returns></returns> string Call(); } }
派生类-猫Cat继承自动物类Animal,拥有自己特有的属性Name,实现了接口的方法Call,方法内容为猫在叫。
using IReflectionApi; using System.IO; namespace ReflectionApi { public class Cat : Animal { public Cat() { name = "Cat"; } private string name; public string Name { get { return name; } set { name = value; } } public string Call() { string nowDateTimeStr = System.DateTime.Now.ToString("yyyyMMdd-HHmmss"); return nowDateTimeStr + "\r\n" + name + "\r\n" + "喵喵"; } } }
派生类-狗Dog继承自动物类Animal,拥有自己特有的属性Name,实现了接口的方法Call,方法内容为狗在叫。
using IReflectionApi; using System.IO; namespace ReflectionApi { public class Dog : Animal { public Dog() { name = "Dog"; } private string name; public string Name { get { return name; } set { name = value; } } public string Call() { string nowDateTimeStr = System.DateTime.Now.ToString("yyyyMMdd-HHmmss"); return nowDateTimeStr + "\r\n" + name + "\r\n" + "汪汪"; } } }
业务层代码
using IReflectionApi; using ReflectionApi; using System; using System.Windows.Forms; namespace CsharpReflection { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void DoCall(string AnimalType) { string dllName = textBox1.Text.Trim();//命名空间.类名,程序集 Type type = System.Type.GetType(dllName); if (type == null) { label1.Text = "找不到类型:" + dllName; return; } object instance = Activator.CreateInstance(type, null); if (instance == null) { label1.Text = "找不到类型:" + dllName; return; } IAnimal animal = instance as IAnimal; label1.Text = animal.Call(); //if (AnimalType=="Cat") //{ // Cat cat = instance as Cat; // label1.Text = cat.Call(); //} //if (AnimalType == "Dog") //{ // Dog dog = instance as Dog; // label1.Text = dog.Call(); //} } private void button1_Click(object sender, EventArgs e) { string animalType = textBox1.Text; DoCall(animalType); } private void Form1_Load(object sender, EventArgs e) { } } }
为什么要使用接口?
不使用接口的处理情况:
反射dll串命名规范为【命名空间.类名,程序集】,现有dll串【ReflectionApi.Cat,ReflectionApi】,需要动态创建类型,此时需要根据dll串中的【类名】去判断反射之后的类型具体是哪种类型。然后实例化该类型,再调用该类型的方法,如下:
string AnimalType="Cat"; object instance = Activator.CreateInstance(“ReflectionApi.Cat,ReflectionApi”, null); if (AnimalType=="Cat") { Cat cat = instance as Cat; label1.Text = cat.Call(); } if (AnimalType == "Dog") { Dog dog = instance as Dog; label1.Text = dog.Call(); }
如果扩展了很多Animal的类型,如新增monkey猴子时,首先你要添加一个Monkey的类,然后在业务调用的时候又要写if判断。无法达到直接根据dll串动态实例化某个类型的效果。
使用接口的情况下:
dll串ReflectionApi.Cat,ReflectionApi通过反射取得一个对象object,此时再将object转为接口类型animal去调用接口的方法。不关心此时的派生类是Dog还是Cat,后续再新增其他的派生类时,业务层的调用永远是用接口类去调用,方便维护。如下:
object instance = Activator.CreateInstance(“ReflectionApi.Cat,ReflectionApi”, null); IAnimal animal = instance as IAnimal; label1.Text = animal.Call();
实现效果: