C#中接口的实例化
一、接口回调
就是继承中的向上转型。父类 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();
}