好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#实现动态创建接口并调用的实例

本文简单介绍如何动态创建接口 interface 的实现实例对象,包含两个知识点:

1.如何获取接口 interface 的所有实现实例对象? 2.如何判断实例对象的构造函数是否有参数? 准备工作

首先新建一个名为 IAnimal 的 interface 接口对象,并定义一个 Cry 方法。

namespace DynamicCreate { /// <summary> /// 动物 /// </summary> public interface IAnimal { /// <summary> /// 叫 /// </summary> public void Cry(); } }

然后,我们分别新建一个 Dog , Cat 对象,并分别实现 Cry 方法。

其中, Dog 的构造函数中包含一个名为 name 的参数。

namespace DynamicCreate { /// <summary> /// 狗 /// </summary> public class Dog : IAnimal { /// <summary> /// 名字 /// </summary> private string _name { get; } /// <summary> /// 有参构造函数 /// </summary> /// <param name="name">狗名</param> public Dog(string name) { _name = name; } /// <summary> /// 狗叫 /// </summary> public void Cry() { Console.WriteLine($"{_name}汪汪汪"); } } }

Cat 的构造函数则为无参构造函数。

namespace DynamicCreate { /// <summary> /// 猫 /// </summary> public class Cat : IAnimal { /// <summary> /// 无参构造函数 /// </summary> public Cat() { } /// <summary> /// 猫叫 /// </summary> public void Cry() { Console.WriteLine("喵喵喵"); } } }

常规的调用方法如下所示。

IAnimal animal_Dog = new Dog("旺财"); animal_Dog.Cry(); IAnimal animal_Cat = new Cat(); animal_Cat.Cry();

运行结果如图所示

如果我们想要一次性将所有实现了 IAnimal 接口对象 Cry 方法的实例全部执行一遍,只能一个对象一个对象的初始化,然后调用 cry 方法。这样太麻烦,我们可以通过动态创建对象并执行对象的方法来实现这个效果。  

下面,我们将开始动态创建所有实现。第一步,我们需要先获取到所有实现了 IAnimal 实例对象。

1.如何获取接口interface的所有实现实例对象?

通过反射来获取当前项目中的程序集对象列表,并根据程序集对象的类型来获取继承或实现了 IAnimal 接口的对象列表。

//获取实现接口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); }

现在,我们已经得到了所有实现 IAnimal 接口的实例对象。讲道理来说,我们就可以用 Activator 动态创建这些对象了。我们可以使用下面的代码来实现批量动态创建对象。

foreach (Type t in types) { var animal = (IAnimal)Activator.CreateInstance(t)!; animal.Cry(); }

然而,却出现一个错误提示: Dog 不包含一个无参构造函数。

所以,创建时需要将 Dog 的构造函数参数 name 传递进去,如下所示。

foreach (Type t in types) { var animal = (IAnimal)Activator.CreateInstance(t, new object[] { "阿黄" })!; animal.Cry(); }

然而,再次提示: Cat 的构造函数不存在。

这是因为 Cat 不包含一个带参数的构造函数,所示无法初始化 Cat 对象。所以,我们需要判断对象是否是有参构造函数或无参构造函数。

2.如何判断实例对象的构造函数是否有参数?

我们可以通过 GetConstructors 方法来获取对象的构造函数集合,并通过 GetParameters 方法获取到构造函数的参数集合,判断构造函数的参数集合是否为空即可判断该对象的构造函数是否为有参或无参构造函数。

foreach (Type v in types) { if (v.GetConstructors().Any(x => x.GetParameters().Any())) { Console.WriteLine($"{v.Name}=>有参构造函数"); } else { Console.WriteLine($"{v.Name}=>无参构造函数"); } }

  

现在,我们可以愉快的创建对象,并调用对象的方法了。

foreach (Type t in types) { IAnimal animal; if (t.GetConstructors().Any(x => x.GetParameters().Any())) { //有参构造函数 //动态创建IAnimal的有参构造函数实现实例对象Dog animal = (IAnimal)Activator.CreateInstance(t, new object[] { "阿黄" })!; } else { //无参构造函数 //动态创建IAnimal的无参构造函数实现实例对象Cat animal = (IAnimal)Activator.CreateInstance(t, new object[] { })!; } animal.Cry(); }

最后,附上完整代。

GitHub

码云

到此这篇关于C#实现动态创建接口并调用的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持。

查看更多关于C#实现动态创建接口并调用的实例的详细内容...

  阅读:46次