C# 传递接口而不是对象实例

C# 传递接口而不是对象实例,c#,.net,oop,interface,C#,.net,Oop,Interface,以SqlBulkCopy.WriteToServer()方法为例。其中一个重载将IDataReader作为参数。我的问题是,将接口传递给方法而不是对象实例本身有什么好处 形式参数类型是接口类型-这意味着您可以传入实现该接口的任何对象(或者更确切地说,是实现该接口的对象的实例) 您不是在传递接口,而是在传递符合接口定义的约定的对象 因此,如果您的数据源是SQL Server,您将传递一个SqlDataReader,如果是Oracle,则传递一个OracleDataReader 您还可以实现自己的数

以SqlBulkCopy.WriteToServer()方法为例。其中一个重载将IDataReader作为参数。我的问题是,将接口传递给方法而不是对象实例本身有什么好处


形式参数类型是接口类型-这意味着您可以传入实现该接口的任何对象(或者更确切地说,是实现该接口的对象的实例)

您不是在传递接口,而是在传递符合接口定义的约定的对象

因此,如果您的数据源是SQL Server,您将传递一个
SqlDataReader
,如果是Oracle,则传递一个
OracleDataReader

您还可以实现自己的数据读取器并将其传递给函数,甚至编写一个模拟数据读取器来彻底测试该方法

这是一个众所周知的设计原则-

来自MSDN-:

接口是一种功能强大的编程工具,因为它们允许您将对象的定义与其实现分离


实际上,它希望您传递实现接口的类型的实例,而不是接口本身


当方法只关心接口声明的方法时,使用接口类型。只要对象实现了该接口,就可以在对象上调用其中定义的方法。

对于该接口,可以有许多可能的实现。与其依赖于实际的具体类,不如依赖于抽象(在本例中是一个接口)——这允许更好的灵活性和可测试性


这还将重点放在
WriteToServer()真正需要的内容上
method-其契约要求的唯一一件事是调用方传入提供由
IDataReader
接口声明的方法/属性的具体类的任何实例。

传递接口意味着您可以传递实现该接口的任何对象,而不仅仅是一个特定的对象反对

这使得代码更加灵活,因为它不必知道现在或将来可能实现接口的所有对象


它还使它更加健壮,因为它只需要处理接口上已知和定义的属性和方法。

当一个方法将其一个参数列为接口时,它不会要求您传入该接口的实例(无论如何,这是不可能的,您可以创建接口的实例),它要求您传入实现该接口的任何对象

例如:

interface IMyObject {
    public void SomeMethod();
}

public class MyObject : IMyObject {
    public void SomeMethod() {
        // implementing code here
    }
}
现在可以将MyObject的任何实例作为IMyObject类型的参数传递:)


我希望这是有道理的

这是接口的原因之一-在本例中,接口的所有使用者(即函数)关心的是它可以读取数据-它不介意它是来自
SqlDataReader
还是来自
OleDataReader
或任何其他提供程序-替代方法是为每个可能的数据读取器提供实际上完全相同的单独重载(这当然是不切实际的,因为有人可能会为dBase或更奇特的数据库引擎想出一种方法)

如果您想了解更多关于这种编程方式的理由,请查找关键字“多态性”。即使一个方法有一个
IDataReader
参数,它仍然会得到一个对象实例…即实现该接口的任何类型中的一个。您不能将接口本身传递给一个方法(作为
类型
对象除外)@stakx因此,无论接口在该对象实例中是如何实现的,调用方方法基本上都将使用传递的对象?因此,在WriteToServer()方法的封面后面,它正在调用一个方法(或多个方法)IDataReader接口是从传递给该方法的对象实例定义的吗?这是绝对有意义的。我发现它增加了相当多的灵活性,并且不需要特定的类作为依赖项,特别是对于使用IDataReader接口的方法的许多类来说愿意使用抽象类而不是接口(只是为了参数)。你能用一个抽象类作为一个方法的参数,并传递所有继承该抽象类的子类吗?为什么不这样做?顺便说一句,关于程序的伟大文章是一个接口,而不是一个实现。肯定会喝一杯咖啡,然后享受剩下的阅读。@Surfer-是的,你当然可以使用abstr在这种情况下使用act类。同样的一组参数也适用(我会说“程序是抽象的,而不是实现的”).作为通信媒介的接口更显式,仅此而已。是什么使它们更显式?似乎没有实现的抽象类中的方法与接口中的方法具有相同的占用空间。@Surfer-单词…以及一个接口根本没有实现的事实(而抽象类可以有一些,通常也有)。它是一个纯契约,接口的用户不希望或不需要查看代码来确定它是否实现了任何东西。
public class YourObject {
    public void DoSomething(IMyObject o) {
        // some code here
    }
}

YourObject yo = new YourObject();
MyObject   mo = new MyObject();
yo.DoSomething(mo); // works