C#實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建接口并調(diào)用的實(shí)例
本文簡(jiǎn)單介紹如何動(dòng)態(tài)創(chuàng)建接口interface的實(shí)現(xiàn)實(shí)例對(duì)象,包含兩個(gè)知識(shí)點(diǎn):
- 1.如何獲取接口
interface的所有實(shí)現(xiàn)實(shí)例對(duì)象? - 2.如何判斷實(shí)例對(duì)象的構(gòu)造函數(shù)是否有參數(shù)?
準(zhǔn)備工作
首先新建一個(gè)名為IAnimal的interface接口對(duì)象,并定義一個(gè)Cry方法。
namespace DynamicCreate
{
/// <summary>
/// 動(dòng)物
/// </summary>
public interface IAnimal
{
/// <summary>
/// 叫
/// </summary>
public void Cry();
}
}
然后,我們分別新建一個(gè)Dog,Cat對(duì)象,并分別實(shí)現(xiàn)Cry方法。
其中,Dog的構(gòu)造函數(shù)中包含一個(gè)名為name的參數(shù)。
namespace DynamicCreate
{
/// <summary>
/// 狗
/// </summary>
public class Dog : IAnimal
{
/// <summary>
/// 名字
/// </summary>
private string _name { get; }
/// <summary>
/// 有參構(gòu)造函數(shù)
/// </summary>
/// <param name="name">狗名</param>
public Dog(string name)
{
_name = name;
}
/// <summary>
/// 狗叫
/// </summary>
public void Cry()
{
Console.WriteLine($"{_name}汪汪汪");
}
}
}
Cat的構(gòu)造函數(shù)則為無(wú)參構(gòu)造函數(shù)。
namespace DynamicCreate
{
/// <summary>
/// 貓
/// </summary>
public class Cat : IAnimal
{
/// <summary>
/// 無(wú)參構(gòu)造函數(shù)
/// </summary>
public Cat()
{
}
/// <summary>
/// 貓叫
/// </summary>
public void Cry()
{
Console.WriteLine("喵喵喵");
}
}
}
常規(guī)的調(diào)用方法如下所示。
IAnimal animal_Dog = new Dog("旺財(cái)");
animal_Dog.Cry();
IAnimal animal_Cat = new Cat();
animal_Cat.Cry();
運(yùn)行結(jié)果如圖所示

如果我們想要一次性將所有實(shí)現(xiàn)了IAnimal接口對(duì)象Cry方法的實(shí)例全部執(zhí)行一遍,只能一個(gè)對(duì)象一個(gè)對(duì)象的初始化,然后調(diào)用cry方法。這樣太麻煩,我們可以通過(guò)動(dòng)態(tài)創(chuàng)建對(duì)象并執(zhí)行對(duì)象的方法來(lái)實(shí)現(xiàn)這個(gè)效果?! ?/p>
下面,我們將開(kāi)始動(dòng)態(tài)創(chuàng)建所有實(shí)現(xiàn)。第一步,我們需要先獲取到所有實(shí)現(xiàn)了IAnimal實(shí)例對(duì)象。
1.如何獲取接口interface的所有實(shí)現(xiàn)實(shí)例對(duì)象?
通過(guò)反射來(lái)獲取當(dāng)前項(xiàng)目中的程序集對(duì)象列表,并根據(jù)程序集對(duì)象的類(lèi)型來(lái)獲取繼承或?qū)崿F(xiàn)了IAnimal接口的對(duì)象列表。
//獲取實(shí)現(xiàn)接口IAnimal的實(shí)例對(duì)象
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IAnimal))))
.ToList();
我們將結(jié)果打印出來(lái)看一下
foreach (Type t in types)
{
Console.WriteLine(t.Name);
}

現(xiàn)在,我們已經(jīng)得到了所有實(shí)現(xiàn)IAnimal接口的實(shí)例對(duì)象。講道理來(lái)說(shuō),我們就可以用Activator動(dòng)態(tài)創(chuàng)建這些對(duì)象了。我們可以使用下面的代碼來(lái)實(shí)現(xiàn)批量動(dòng)態(tài)創(chuàng)建對(duì)象。
foreach (Type t in types)
{
var animal = (IAnimal)Activator.CreateInstance(t)!;
animal.Cry();
}
然而,卻出現(xiàn)一個(gè)錯(cuò)誤提示:Dog不包含一個(gè)無(wú)參構(gòu)造函數(shù)。

所以,創(chuàng)建時(shí)需要將Dog的構(gòu)造函數(shù)參數(shù)name傳遞進(jìn)去,如下所示。
foreach (Type t in types)
{
var animal = (IAnimal)Activator.CreateInstance(t, new object[] { "阿黃" })!;
animal.Cry();
}
然而,再次提示:Cat的構(gòu)造函數(shù)不存在。

這是因?yàn)?code>Cat不包含一個(gè)帶參數(shù)的構(gòu)造函數(shù),所示無(wú)法初始化Cat對(duì)象。所以,我們需要判斷對(duì)象是否是有參構(gòu)造函數(shù)或無(wú)參構(gòu)造函數(shù)。
2.如何判斷實(shí)例對(duì)象的構(gòu)造函數(shù)是否有參數(shù)?
我們可以通過(guò)GetConstructors方法來(lái)獲取對(duì)象的構(gòu)造函數(shù)集合,并通過(guò)GetParameters方法獲取到構(gòu)造函數(shù)的參數(shù)集合,判斷構(gòu)造函數(shù)的參數(shù)集合是否為空即可判斷該對(duì)象的構(gòu)造函數(shù)是否為有參或無(wú)參構(gòu)造函數(shù)。
foreach (Type v in types)
{
if (v.GetConstructors().Any(x => x.GetParameters().Any()))
{
Console.WriteLine($"{v.Name}=>有參構(gòu)造函數(shù)");
}
else
{
Console.WriteLine($"{v.Name}=>無(wú)參構(gòu)造函數(shù)");
}
}

現(xiàn)在,我們可以愉快的創(chuàng)建對(duì)象,并調(diào)用對(duì)象的方法了。
foreach (Type t in types)
{
IAnimal animal;
if (t.GetConstructors().Any(x => x.GetParameters().Any()))
{
//有參構(gòu)造函數(shù)
//動(dòng)態(tài)創(chuàng)建IAnimal的有參構(gòu)造函數(shù)實(shí)現(xiàn)實(shí)例對(duì)象Dog
animal = (IAnimal)Activator.CreateInstance(t, new object[] { "阿黃" })!;
}
else
{
//無(wú)參構(gòu)造函數(shù)
//動(dòng)態(tài)創(chuàng)建IAnimal的無(wú)參構(gòu)造函數(shù)實(shí)現(xiàn)實(shí)例對(duì)象Cat
animal = (IAnimal)Activator.CreateInstance(t, new object[] { })!;
}
animal.Cry();
}

最后,附上完整代。
到此這篇關(guān)于C#實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建接口并調(diào)用的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#通過(guò)Win32API設(shè)置客戶(hù)端系統(tǒng)時(shí)間的方法詳解
在日常工作中,有時(shí)可能會(huì)需要獲取或修改客戶(hù)端電腦的系統(tǒng)時(shí)間,比如軟件設(shè)置了Licence有效期,本文以一個(gè)簡(jiǎn)單的小例子,簡(jiǎn)述如何通過(guò)C#獲取和設(shè)置客戶(hù)端電腦的系統(tǒng)時(shí)間,僅供學(xué)習(xí)分享使用,如有不足之處,還請(qǐng)指正,需要的朋友可以參考下2024-06-06
字符串替換Replace僅替換第一個(gè)字符串匹配項(xiàng)
C#里面的String.Replace(string,string)方法替換的時(shí)候是替換所有的匹配項(xiàng),我們需要只替換第一個(gè)匹配項(xiàng),寫(xiě)一個(gè)方法來(lái)實(shí)現(xiàn)這個(gè)功能2013-12-12
C#執(zhí)行Javascript代碼的幾種方法總結(jié)
本篇文章主要是對(duì)C#執(zhí)行Javascript代碼的幾種方法進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-01-01
C#字符串左不足位數(shù)時(shí)補(bǔ)充0的幾種方式
想讓一個(gè)整數(shù)或字符串轉(zhuǎn)換為字符串后,如果其長(zhǎng)度不足5位,則在左邊補(bǔ)充0直到達(dá)到5位,本文給大家介紹了C#字符串左不足位數(shù)時(shí)補(bǔ)充0的幾種方式,感興趣的朋友可以參考下2024-04-04
DevExpress設(shè)置FocusedNode背景色的方法
這篇文章主要介紹了DevExpress設(shè)置FocusedNode背景色的方法,很實(shí)用的功能,需要的朋友可以參考下2014-08-08
CAD2008+VS2008開(kāi)發(fā)ObjectARX加載失敗問(wèn)題(推薦)
這篇文章主要介紹了CAD2008+VS2008開(kāi)發(fā)ObjectARX加載失敗問(wèn)題,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04

