以SqlBulkCopy.WriteToServer()方法为例。其中一个重载采用IDataReader作为参数。我的问题是,将接口传递给方法而不是对象实例本身有什么好处/好处?
答案 0 :(得分:9)
您可以为该一个界面提供许多可能的实现。它更好地依赖于抽象(在这种情况下是一个接口)而不是实际的具体类 - 这样可以提供更好的灵活性和可测试性。
这也将焦点放在WriteToServer()
方法真正需要的内容上 - 它的合同唯一需要的是调用者传入提供的具体类的任何实例IDataReader
接口声明的方法/属性。
答案 1 :(得分:9)
传递接口意味着您可以传递实现该接口的任何对象而不仅仅是一个特定对象。
这使得代码更加灵活,因为它不必知道现在或将来可能实现接口的所有可能对象。
它还使它更加健壮,因为它只需要处理众所周知和定义的接口属性和方法。
答案 2 :(得分:6)
形式参数类型是接口类型 - 这意味着您可以传入实现此接口的任何对象(或者更确切地说,是实现接口的对象的实例)。
您没有传入接口,而是传入符合接口定义的合同的对象。
因此,如果您的数据源是SQL Server,那么您将传递SqlDataReader
(如果是Oracle)OracleDataReader
。
您还可以实现自己的数据读取器并将其传递给函数,甚至可以编写模拟数据读取器来彻底测试该方法。
这是众所周知的设计原则 - Program to an Interface, not an implementation。
来自MSDN - When to Use Interfaces:
接口是一种功能强大的编程工具,因为它们允许您将对象的定义与其实现分开。
答案 3 :(得分:3)
当一个方法将其中一个参数列为接口时,它不会要求您传入该接口的实例(这无论如何都是不可能的,您可以创建接口实例),它要求您传入任何接口实现该接口的对象。
示例:
interface IMyObject {
public void SomeMethod();
}
public class MyObject : IMyObject {
public void SomeMethod() {
// implementing code here
}
}
您现在可以将任何MyObject实例作为IMyObject类型的参数传递
public class YourObject {
public void DoSomething(IMyObject o) {
// some code here
}
}
YourObject yo = new YourObject();
MyObject mo = new MyObject();
yo.DoSomething(mo); // works
我希望这是有道理的!
答案 4 :(得分:2)
实际上,它希望您传递一个实现接口的类型的实例,而不是接口本身。
当方法唯一关心的是接口声明的方法时,使用接口类型。只要对象实现了该接口,就可以在对象上调用其中定义的方法。
答案 5 :(得分:1)
这是接口的原因之一 - 在这个例子中,接口的所有消费者(即函数)关心的是它可以读取数据 - 它不介意它是否来自SqlDataReader
或OleDataReader
或任何其他提供者 - 替代提供单独的重载,对于每个可能的数据读取器实际上是相同的(这当然是不切实际的,因为有人可能想出一个,比如dBase或更多异国情调的数据库引擎)