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

 更新时间:2021年11月24日 17:28:29   作者:摇曳de风筝  
这篇文章介绍了C#实现动态创建接口并调用,文中通过实例代码介绍的非常详细。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

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

准备工作

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

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

然后,我们分别新建一个DogCat对象,并分别实现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#通过Win32API设置客户端系统时间的方法详解

    C#通过Win32API设置客户端系统时间的方法详解

    在日常工作中,有时可能会需要获取或修改客户端电脑的系统时间,比如软件设置了Licence有效期,本文以一个简单的小例子,简述如何通过C#获取和设置客户端电脑的系统时间,仅供学习分享使用,如有不足之处,还请指正,需要的朋友可以参考下
    2024-06-06
  • C#关键字之重载Overload介绍

    C#关键字之重载Overload介绍

    这篇文章介绍了C#关键字之重载Overload,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 深入解析C#中的async和await关键字

    深入解析C#中的async和await关键字

    C#语言中的async和await关键字使得编写异步代码变得更加简洁和易读,本文将深入解析C#中的async和await,帮助您更好地理解它们的工作原理和用法,,需要的朋友可以参考下
    2024-05-05
  • 字符串替换Replace仅替换第一个字符串匹配项

    字符串替换Replace仅替换第一个字符串匹配项

    C#里面的String.Replace(string,string)方法替换的时候是替换所有的匹配项,我们需要只替换第一个匹配项,写一个方法来实现这个功能
    2013-12-12
  • C#执行Javascript代码的几种方法总结

    C#执行Javascript代码的几种方法总结

    本篇文章主要是对C#执行Javascript代码的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • C#字符串左不足位数时补充0的几种方式

    C#字符串左不足位数时补充0的几种方式

    想让一个整数或字符串转换为字符串后,如果其长度不足5位,则在左边补充0直到达到5位,本文给大家介绍了C#字符串左不足位数时补充0的几种方式,感兴趣的朋友可以参考下
    2024-04-04
  • DevExpress设置FocusedNode背景色的方法

    DevExpress设置FocusedNode背景色的方法

    这篇文章主要介绍了DevExpress设置FocusedNode背景色的方法,很实用的功能,需要的朋友可以参考下
    2014-08-08
  • CAD2008+VS2008开发ObjectARX加载失败问题(推荐)

    CAD2008+VS2008开发ObjectARX加载失败问题(推荐)

    这篇文章主要介绍了CAD2008+VS2008开发ObjectARX加载失败问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 详解C#调用matlab生成的dll库

    详解C#调用matlab生成的dll库

    这篇文章主要介绍了C#调用matlab生成的dll库,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • 详解如何在C#中处理空值

    详解如何在C#中处理空值

    在任何编程语言中开发应用程序时,经常会遇到空异常或空引用异常,那么下面让我们探讨一下在C#中处理空值的各种方法吧,需要的可以收藏下
    2023-07-07

最新评论