C#中接口的实例化

参考文章:

【学习笔记】c#中接口的实例化 - pizzabig - 博客园 (cnblogs.com)

C#动态创建接口的实现实例对象_c#接口开发实例_摇曳的风筝的博客-CSDN博客

如果实例化的接口 引用  继承自同一个接口的 不同的  类,这个实例就可以调用这些实现的该接口的所有方法

一、接口回调

这就是继承中的向上转型。父类 FL=new 子类();只不过这里的父类就是interface接口。(个人认为这里不管是class的override还是interface的重写,都是一样的用法)

可以把实现某一接口类创建的对象的引用赋给该接口声明的接口变量,那么该 
接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量调用被类实现的接口 
中的方法时,就是通知相应的对象调用接口方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace InterfaceTest {
    interface IMyInterface {
        void AMethod();
    }
    class Test : IMyInterface {
        public void AMethod() {
            Console.WriteLine("Extends from IMyInterface in Test1");
        }

    }
    class Test2 : IMyInterface {
        public void AMethod() {
            Console.WriteLine("Extends from IMyInterface in Test2");
        }

    }

    class Program {
        static void Main(string[] args) {
            IMyInterface a = new Test();
            IMyInterface b=new Test2();
            a.AMethod();
            b.AMethod();
            Console.ReadKey();
        }

    }
}

执行结果如下: 
Extends from IMyInterface in Test1 
Extends from IMyInterface in Test2

接口对象的实例化实际上是一个接口对象作为一个引用 
,指向实现了它方法的那个类中的所有方法,这一点非常象C++中的函数指针(在C#中类似委托),但是却是有 
区别的。C#中的接口对象实例化实际上是一对多的,而C++中的函数指针是一对一的。 
但是需要注意的是,接口对象的实例化必须用实现它的类来实例化,而不能用接口本身实 
例化。用接口本身实例化它自己的对象在C#中是不允许的。

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

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

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

//获取实现接口IAnimal的实例对象
var types = AppDomain.CurrentDomain.GetAssemblies()
                        .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IAnimal))))
                        .ToList(); 

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

 上述方法只能用于包含无参构造函数的类,只包含有参构造函数的类会出错

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();

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值