C#實現(xiàn)動態(tài)創(chuàng)建接口并調(diào)用的實例
本文簡單介紹如何動態(tài)創(chuàng)建接口interface
的實現(xiàn)實例對象,包含兩個知識點:
- 1.如何獲取接口
interface
的所有實現(xiàn)實例對象? - 2.如何判斷實例對象的構造函數(shù)是否有參數(shù)?
準備工作
首先新建一個名為IAnimal
的interface
接口對象,并定義一個Cry
方法。
namespace DynamicCreate { /// <summary> /// 動物 /// </summary> public interface IAnimal { /// <summary> /// 叫 /// </summary> public void Cry(); } }
然后,我們分別新建一個Dog
,Cat
對象,并分別實現(xiàn)Cry
方法。
其中,Dog
的構造函數(shù)中包含一個名為name
的參數(shù)。
namespace DynamicCreate { /// <summary> /// 狗 /// </summary> public class Dog : IAnimal { /// <summary> /// 名字 /// </summary> private string _name { get; } /// <summary> /// 有參構造函數(shù) /// </summary> /// <param name="name">狗名</param> public Dog(string name) { _name = name; } /// <summary> /// 狗叫 /// </summary> public void Cry() { Console.WriteLine($"{_name}汪汪汪"); } } }
Cat
的構造函數(shù)則為無參構造函數(shù)。
namespace DynamicCreate { /// <summary> /// 貓 /// </summary> public class Cat : IAnimal { /// <summary> /// 無參構造函數(shù) /// </summary> public Cat() { } /// <summary> /// 貓叫 /// </summary> public void Cry() { Console.WriteLine("喵喵喵"); } } }
常規(guī)的調(diào)用方法如下所示。
IAnimal animal_Dog = new Dog("旺財"); animal_Dog.Cry(); IAnimal animal_Cat = new Cat(); animal_Cat.Cry();
運行結果如圖所示
如果我們想要一次性將所有實現(xiàn)了IAnimal
接口對象Cry
方法的實例全部執(zhí)行一遍,只能一個對象一個對象的初始化,然后調(diào)用cry
方法。這樣太麻煩,我們可以通過動態(tài)創(chuàng)建對象并執(zhí)行對象的方法來實現(xiàn)這個效果?! ?/p>
下面,我們將開始動態(tài)創(chuàng)建所有實現(xiàn)。第一步,我們需要先獲取到所有實現(xiàn)了IAnimal
實例對象。
1.如何獲取接口interface的所有實現(xiàn)實例對象?
通過反射來獲取當前項目中的程序集對象列表,并根據(jù)程序集對象的類型來獲取繼承或實現(xiàn)了IAnimal
接口的對象列表。
//獲取實現(xiàn)接口IAnimal的實例對象 var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IAnimal)))) .ToList();
我們將結果打印出來看一下
foreach (Type t in types) { Console.WriteLine(t.Name); }
現(xiàn)在,我們已經(jīng)得到了所有實現(xiàn)IAnimal
接口的實例對象。講道理來說,我們就可以用Activator
動態(tài)創(chuàng)建這些對象了。我們可以使用下面的代碼來實現(xiàn)批量動態(tài)創(chuàng)建對象。
foreach (Type t in types) { var animal = (IAnimal)Activator.CreateInstance(t)!; animal.Cry(); }
然而,卻出現(xiàn)一個錯誤提示:Dog
不包含一個無參構造函數(shù)。
所以,創(chuàng)建時需要將Dog
的構造函數(shù)參數(shù)name
傳遞進去,如下所示。
foreach (Type t in types) { var animal = (IAnimal)Activator.CreateInstance(t, new object[] { "阿黃" })!; animal.Cry(); }
然而,再次提示:Cat
的構造函數(shù)不存在。
這是因為Cat
不包含一個帶參數(shù)的構造函數(shù),所示無法初始化Cat
對象。所以,我們需要判斷對象是否是有參構造函數(shù)或無參構造函數(shù)。
2.如何判斷實例對象的構造函數(shù)是否有參數(shù)?
我們可以通過GetConstructors
方法來獲取對象的構造函數(shù)集合,并通過GetParameters
方法獲取到構造函數(shù)的參數(shù)集合,判斷構造函數(shù)的參數(shù)集合是否為空即可判斷該對象的構造函數(shù)是否為有參或無參構造函數(shù)。
foreach (Type v in types) { if (v.GetConstructors().Any(x => x.GetParameters().Any())) { Console.WriteLine($"{v.Name}=>有參構造函數(shù)"); } else { Console.WriteLine($"{v.Name}=>無參構造函數(shù)"); } }
現(xiàn)在,我們可以愉快的創(chuàng)建對象,并調(diào)用對象的方法了。
foreach (Type t in types) { IAnimal animal; if (t.GetConstructors().Any(x => x.GetParameters().Any())) { //有參構造函數(shù) //動態(tài)創(chuàng)建IAnimal的有參構造函數(shù)實現(xiàn)實例對象Dog animal = (IAnimal)Activator.CreateInstance(t, new object[] { "阿黃" })!; } else { //無參構造函數(shù) //動態(tài)創(chuàng)建IAnimal的無參構造函數(shù)實現(xiàn)實例對象Cat animal = (IAnimal)Activator.CreateInstance(t, new object[] { })!; } animal.Cry(); }
最后,附上完整代。
到此這篇關于C#實現(xiàn)動態(tài)創(chuàng)建接口并調(diào)用的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
C#中LINQ?to?DataSet操作及DataTable與LINQ相互轉換
這篇文章介紹了C#中LINQ?to?DataSet操作及DataTable與LINQ相互轉換,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05C#表達式樹Expression動態(tài)創(chuàng)建表達式
這篇文章介紹了C#表達式樹Expression動態(tài)創(chuàng)建表達式的方法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-12-12C#通過第三方組件生成二維碼(QR Code)和條形碼(Bar Code)
用C#如何生成二維碼,我們可以通過現(xiàn)有的第三方dll直接來實現(xiàn),下面列出幾種不同的生成方法2016-12-12unity通過Mesh網(wǎng)格繪制圖形(三角形、正方體、圓柱)
這篇文章主要為大家詳細介紹了unity通過Mesh網(wǎng)格繪制圖形:三角形、正方體、圓柱,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11