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 + "\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(); 

实现效果:

 C#反射+继承+接口的应用_程序集

 

 C#反射+继承+接口的应用_类名_02

 

实例源码仓库地址:https://gitee.com/soulsjie/csharp-reflection.git