C#反射+继承+接口的应用
创建一个接口类
创建一个动物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 + "
" + name + "
" + "喵喵";
}
}
}
派生类-狗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 + "
" + name + "
" + "汪汪";
}
}
}
业务层代码
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();
实现效果: