C#反射+繼承+介面的應用
阿新 • • 發佈:2021-07-22
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();
實現效果: