简体   繁体   English

C# - 返回接口的方法

[英]C# - Methods that return interfaces

I'm a little confused on the concept of methods returning interfaces. 我对返回接口的方法的概念有点困惑。 Is there an article or reference that discusses this in some detail? 是否有一篇文章或参考文献详细讨论了这个问题? I'm confused on when/why you might want to do this, and how is it that you can cast an interface to/from the object it's associated with (I think that's right). 我很困惑你何时/为什么要这样做,以及如何将接口转换为与之关联的对象(我认为是正确的)。

I'm confused on when/why you might want to do this, 我很困惑你何时/为什么要这样做,

Returning an interface is good when you want to separate the contract of what something is supposed to do, from the concrete implementation (how it does it). 当你想要从具体的实现(它是如何做的)中分离出应该做什么的契约时,返回一个接口是很好的。 Having an interface allows you to reuse and modify code more easily. 拥有一个接口可以让您更轻松地重用和修改代码。

If you have an interface IFoo and an implementation SimpleFoo that implements IFoo in a naive way you can program against the interface and get basic functionality. 如果你有一个接口IFoo和一个以简单的方式实现IFoo的实现SimpleFoo ,你可以对接口进行编程并获得基本功能。 Later you can make an AdvancedFoo implementation that also implements the same IFoo interface. 稍后您可以创建一个也实现相同IFoo接口的AdvancedFoo实现。 Now you just need to return your new object and the rest of the code will use the new, more advanced class without requiring any changes. 现在您只需要返回新对象,其余代码将使用新的更高级的类,而无需任何更改。 Having the interface also allows you to make the choice of which class to use at runtime. 拥有该接口还允许您选择在运行时使用哪个类。

When your code returns interfaces it also makes it more flexible. 当您的代码返回接口时,它也使它更灵活。 You may currently return a List<T> but if the result only needs to be used as an IEnumerable<T> then you should return this instead. 您当前可能返回List<T>但如果结果只需要用作IEnumerable<T>那么您应该返回它。 Then you can later change your implementation so that the results are generated on the fly (for example with an iterator block) and the calling code will still work. 然后,您可以稍后更改您的实现,以便动态生成结果(例如使用迭代器块),并且调用代码仍然可以工作。

how is it that you can cast an interface to/from the object it's associated with 如何将接口与其关联的对象进行转换

The whole point of interfaces is that you shouldn't need to do this. 接口的全部意义在于您不需要这样做。 You should just use the interface without worrying about what the specific implementation is. 您应该只使用该接口而不必担心具体实现是什么。 The correct method will be called by the runtime. 运行时将调用正确的方法。 If you think you need to cast it could be a sign that your interface is not rich enough to support your needs. 如果您认为需要进行投射,则可能表明您的界面不够丰富,无法满足您的需求。

You can cast if you need to though: 如果你需要,你可以施放:

IFoo foo = getFoo();
SimpleFoo simpleFoo = (SimpleFoo)foo;

Note that this cast can fail and you may want to use as instead: 请注意,此强制转换可能会失败,您可能希望将其as

IFoo foo = getFoo();
SimpleFoo simpleFoo = foo as SimpleFoo;
if (simpleFoo == null)
{
     // Too bad...
}
else
{
    // Now we can use simpleFoo.
}

Sometimes you want to return an interface because it's a general way of returning any class that implements it. 有时您想要返回一个接口,因为它是返回任何实现它的类的一般方法。 You won't have to worry about what the actual class being returned is because you'll be able to call the methods that are in the interface. 您不必担心返回的实际类是什么,因为您将能够调用接口中的方法。

For example: 例如:

public interface IFooBar
{
    String GetData();
}

public class Foo : IFooBar
{
    public String GetData() { return "Foo"; }
}

public class Bar : IFooBar
{
    public String GetData() { return "Bar"; }
}

public class DataManager
{
    public static IFooBar GetFooBar()
    {
        IFooBar foobar = ...
        return foobar;
     }
}

public class MainAppClass
{
     public void SomeMethod()
     {
         //You don't care what type of class you get here
         //you only care that the object you get back let's you
         //call GetData.
         IFooBar foobar = DataManager.GetFooBar();
         String data = foobar.GetData();
         //etc
     }
}

I'm not sure what's confusing about it. 我不确定这有什么令人困惑的。 An interface is basically equivalent to an abstract class that has no non-abstract methods and no declared state (fields). 接口基本上等同于没有非抽象方法且没有声明状态(字段)的抽象类。 So returning an interface is like returning an abstract base class. 所以返回一个接口就像返回一个抽象基类。

The reason you'd want to return an interface instead is that interfaces represent small bundles of functionality rather than full-blown objects. 你想要返回一个接口的原因是接口代表了一小部分功能而不是完整的对象。 A classic example is returning IEnumerable instead of List because even though the underlying object might be a list, the method is really just returning an ordered set of objects and that's all the caller should see. 一个典型的例子是返回IEnumerable而不是List,因为即使底层对象可能是一个列表,该方法实际上只是返回一组有序的对象,这是调用者应该看到的全部内容。 In the future, the method might return an array or some other data structure. 将来,该方法可能会返回一个数组或一些其他数据结构。 But it won't matter to the caller because all the caller sees is IEnumerable. 但是对调用者来说无关紧要,因为所有调用者看到的都是IEnumerable。 This follows the general principle of programming to interfaces instead of implementations. 这遵循编程到接口而不是实现的一般原则。

Methods cannot return an interface itself. 方法本身不能返回接口。 An interface is a description of methods an object should implement. 接口是对象应实现的方法的描述。 You can't return a list of methods an object needs to have. 您无法返回对象需要具有的方法列表。

What you can do is return an instance of an interface. 你可以做的是返回一个接口的实例。 Take code that looks like this: 采用如下代码:

using System.Collections.Generic;

ICollection<int> getCollection() {
    return new LinkedList<int>();
}

This method returns an instance of LinkedList, but its return type is ICollection. 此方法返回LinkedList的实例,但其返回类型为ICollection。 This means you can use the return value of getCollection() wherever you can use an ICollection since LinkedList inherits from ICollection. 这意味着您可以使用getCollection()的返回值,只要您可以使用ICollection,因为LinkedList继承自ICollection。 If the return type was LinkedList, you could only use the return type where a LinkedList was expected, reducing your flexibility. 如果返回类型是LinkedList,则只能使用期望LinkedList的返回类型,从而降低了灵活性。

C# interfaces tutorial C#接口教程

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

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