1. 程式人生 > 其它 >C#反射+繼承+介面的應用

C#反射+繼承+介面的應用

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(); 

實現效果:

例項原始碼倉庫地址:https://gitee.com/soulsjie/csharp-reflection.git