简体   繁体   English

传递接口而不是 object 实例

[英]Passing an interface instead of an object instance

Take for instance the SqlBulkCopy.WriteToServer() method.以 SqlBulkCopy.WriteToServer() 方法为例。 One of the overloads takes an IDataReader as the parameter.其中一个重载将 IDataReader 作为参数。 My question is, what's the benefit/advantage to passing an interface to a method instead of the object instance itself?我的问题是,将接口传递给方法而不是 object 实例本身有什么好处/优势?

http://msdn.microsoft.com/en-us/library/434atets.aspx http://msdn.microsoft.com/en-us/library/434atets.aspx

You can have many possible implementations for that one interface.对于那个接口,您可以有许多可能的实现。 Its better to depend on an abstraction (in this case an interface) than an actual concrete class - this allows much better flexibility and testability.依赖抽象(在这种情况下是接口)比实际的具体 class 更好 - 这允许更好的灵活性和可测试性。

This also puts the focus on what is really required by the WriteToServer() method - the only thing its contract requires is for the caller to pass in any instance of a concrete class that provides the methods / properties declared by the IDataReader interface.这也将重点放在了WriteToServer()方法真正需要的东西上——它的合约唯一需要的是让调用者传入提供由IDataReader接口声明的方法/属性的具体 class 的任何实例。

Passing an interface means that you can pass any object that implements that interface not just one particular object.传递接口意味着您可以传递任何实现该接口的 object,而不仅仅是一个特定的 object。

This makes the code more flexible as it doesn't have to know about all the possible objects that may implement the interface now or in the future.这使代码更加灵活,因为它不必知道现在或将来可能实现接口的所有可能对象。

It also makes it more robust as it only has to deal with the properties and methods on the interface which are well known and defined.它还使它更加健壮,因为它只需要处理接口上众所周知和定义的属性和方法。

The formal parameter type is an interface type - that means that you can pass in any object that implements this interface (or rather, an instance of an object that implements the interface).形参类型是接口类型——这意味着您可以传入任何实现此接口的 object(或者更确切地说,是实现该接口的 object 的实例)。

You are not passing in an interface, you are passing in an object that conforms to the contract defined by the interface.您不是在传递接口,而是在传递符合接口定义的合同的object

So, if your data source is SQL Server, you would pass a SqlDataReader , if Oracle, an OracleDataReader .因此,如果您的数据源是 SQL 服务器,则您将传递SqlDataReader ,如果 Oracle 则传递OracleDataReader

You could also implement your own data reader and pass that to the function and even write a mock data reader to test the method thoroughly.您还可以实现自己的数据读取器并将其传递给 function,甚至编写一个模拟数据读取器来彻底测试该方法。

This is a well known design principle - Program to an Interface, not an implementation .这是一个众所周知的设计原则 - Program to an Interface, not an implementation

And from MSDN - When to Use Interfaces :并来自 MSDN -何时使用接口

Interfaces are a powerful programming tool because they let you separate the definition of objects from their implementation.接口是一种强大的编程工具,因为它们让您可以将对象的定义与其实现分开。

When a method lists one of its arguments as an interface, it isn't requesting you to pass in an instance of that interface (which is impossible anyway, you can create instances of interfaces), it's asking you to pass in any object that implements that interface.当一个方法将其 arguments 之一列为接口时,它并不要求您传入该接口的实例(无论如何这是不可能的,您可以创建接口实例),它要求您传入任何实现的 object那个界面。

Example:例子:

interface IMyObject {
    public void SomeMethod();
}

public class MyObject : IMyObject {
    public void SomeMethod() {
        // implementing code here
    }
}

You can now pass any instance of MyObject as an argument that is of type IMyObject:)您现在可以将 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

I hope that makes sense!我希望这是有道理的!

Actually, it expects you to pass an instance of a type that implements the interface, rather than the interface itself.实际上,它希望您传递实现接口的类型的实例,而不是接口本身。

The interface type is used when the only thing the method cares about are the methods declared by the interface.当方法只关心接口声明的方法时,使用接口类型。 As long as the object implements that interface, methods defined in it can be invoked on the object.只要 object 实现了该接口,其中定义的方法就可以在 object 上调用。

This is one of the reasons for interfaces - in this example, all the consumer of the interface (ie the function) cares about is that it can read data - it doesn't mind whether it's from an SqlDataReader or an OleDataReader or for any other provider - the alternate would be providing separate overloads that are virtually identical for every possible Data Reader (which is of course impractical, given someone may come up with one for, say dBase or a more exotic database engine)这是接口的原因之一——在这个例子中,接口的所有消费者(即函数)关心的是它可以读取数据——它不介意它是来自SqlDataReader还是OleDataReader或任何其他provider - 替代方案将为每个可能的 Data Reader 提供几乎相同的单独重载(这当然是不切实际的,因为有人可能会为 dBase 或更奇特的数据库引擎提供一个)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM