了解接口 [英] Understanding Interfaces

查看:117
本文介绍了了解接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我仍然无法理解哪些接口有益。我读了一些教程,但我仍然不知道它们对于其他什么是他们让你的课程保持承诺和他们帮助多重继承。

I am still having trouble understanding what interfaces are good for. I read a few tutorials and I still don't know what they really are for other then "they make your classes keep promises" and "they help with multiple inheritance".

多数民众赞成。我仍然不知道什么时候我甚至会在实际工作示例中使用界面,甚至何时确定何时使用它。

Thats about it. I still don't know when I would even use an interface in a real work example or even when to identify when to use it.

由于我对界面的了解有限可以提供帮助,因为如果某些东西实现它,那么你可以通过接口允许传入类似不同的类而不用担心它不是正确的参数。

From my limited knowledge of interfaces they can help because if something implements it then you can just pass the interface in allowing to pass in like different classes without worrying about it not being the right parameter.

但我从不知道这个真正的意义,因为他们通常在这一点上停止显示代码在通过界面后会做什么,如果他们这样做,似乎他们没有做任何有用的事情,我可以看到和哇,他们会帮助一个现实世界的例子。

But I never know what the real point of this since they usually stop short at this point from showing what the code would do after it passes the interface and if they sort of do it it seems like they don't do anything useful that I could look at and go "wow they would help in a real world example".

所以我想我说的是我正在试图找到一个真实世界的例子,我可以看到接口在行动中。

So what I guess I am saying is I am trying to find a real world example where I can see interfaces in action.

我也不明白你可以像这样对象的引用:

I also don't understand that you can do like a reference to an object like this:

ICalculator myInterface = new JustSomeClass();

所以现在如果我去myInterface点和intellisense会拉起来我只会看到接口方法和不是JustSomeClass中的其他方法。所以我还没有看到这一点。

So now if I would go myInterface dot and intellisense would pull up I would only see the interface methods and not the other methods in JustSomeClass. So I don't see a point to this yet.

此外,我开始进行单元测试,他们似乎喜欢使用接口,但我仍然不明白为什么。

Also I started to do unit testing where they seem to love to use interfaces but I still don't understand why.

例如这个例子:

public AuthenticationController(IFormsAuthentication formsAuth)
{
    FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
}

public class FormsAuthenticationWrapper : IFormsAuthentication
{
    public void SetAuthCookie(string userName, bool createPersistentCookie)
    {
        FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
    }
    public void SignOut()
    {
        FormsAuthentication.SignOut();
    }
}

public IFormsAuthentication FormsAuth
{
    get;
    set;
}

为什么要打扰这个界面呢?为什么不使用其中的方法制作FormsAuthenticationWrapper并将其称为一天?为什么首先创建一个接口然后让Wrapper实现接口然后最后编写方法?

Like why bother making this interface? Why not just make FormsAuthenticationWrapper with the methods in it and call it a day? Why First make an interface then have the Wrapper implement the interface and then finally write the methods?

然后我不明白这句话的真实含义。

Then I don't get what the statement is really saying.

就像我现在知道该声明说的那样

Like I now know that the statement is saying this

FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();

如果formsAuth为null,则创建一个新的FormsAuthenticationWrapper,然后将其分配给作为Interface的属性。

if formsAuth is null then make a new FormsAuthenticationWrapper and then assign it to the property that is an Interface.

我想这可以追溯到为什么参考的事情。特别是在这种情况下,因为所有方法都完全相同。 Wrapper没有接口没有的任何新方法,我不确定,但是当你这样做时,方法被正确填充(即它们有一个体),它们不会被转换为存根,因为这看起来真的没有意义对我(它会转换回界面)。

I guess it goes back to the whole point of why the reference thing. Especially in this case since all the methods are exactly the same. The Wrapper does not have any new methods that the interface does not have and I am not sure but when you do this the methods are filled right(ie they have a body) they don't get converted to stubs because that would really seem pointless to me(it it would be converted back to an interface).

然后在测试文件中他们有:

Then in the testing file they have:

var formsAuthenticationMock = new Mock<AuthenticationController.IFormsAuthentication>();

所以他们只是传递了FormsAuthentication我猜的所有假的存根。我猜测程序实际运行时会使用包装类,因为它有真正的方法可以执行某些操作(比如签出一个人)。

So they just pass in the FormsAuthentication what I am guessing makes all the fake stubs. I am guessing the wrapper class is used when the program is actually running since it has real methods that do something(like sign a person out).

但是看看新模拟(来自moq)它接受一个类或接口。为什么不再让封装类把那些方法放进然后在新的Mock调用中呢?

But looking at new Mock(from moq) it accepts a class or an interface. Why not just again made the wrapper class put those methods in and then in the new Mock call that?

这不仅仅是为你制作存根吗?

Would that not just make the stubs for you?

推荐答案

接口定义合约

在您提供的示例中,如果传递<$ c $, ?? 运算符只提供默认值c> null 到构造函数,并没有与接口有任何关系。

In the example you provide, the ?? operator just provides a default value if you pass null to the constructor and doesn't really have anything to do with interfaces.

更有意义的是,您可以使用实际的 FormsAuthenticationWrapper 对象,但您也可以实现自己的 IFormsAuthentication 类型与包装类完全无关。界面告诉您实现合同需要实现哪些方法和属性,并允许编译器验证您的对象是否真的履行了该合同(在某种程度上 - 在名称中遵守合同很简单,但在精神上却没有) ,所以如果你不想,你不必使用预先构建的 FormsAuthenticationWrapper 。您可以构建一个完全不同但仍然遵守所需合同的不同类。

What is more relevant is that you might use an actual FormsAuthenticationWrapper object, but you can also implement your own IFormsAuthentication type that has nothing to do with the wrapper class at all. The interface tells you what methods and properties you need to implement to fulfill the contract, and allows the compiler to verify that your object really does honor that contract (to some extent - it's simple to honor a contract in name, but not in spirit), and so you don't have to use the pre-built FormsAuthenticationWrapper if you don't want to. You can build a different class that works completely differently but still honors the required contract.

在这方面,接口很像普通继承,但有一个重要区别。在C#中,类只能从一种类型继承,但可以实现许多接口。因此,接口允许您在一个类中完成多个合同。一个对象可以一个IFormsAuthentication对象而也是其他东西,比如IEnumerable。

In this respect interfaces are much like normal inheritance, with one important difference. In C# a class can only inherit from one type but can implement many interfaces. So interfaces allow you to fulfill multiple contracts in one class. An object can be an IFormsAuthentication object and also be something else, like IEnumerable.

接口更有用当你从另一个方向看它时:它们允许你对待许多不同的类型,就好像它们都是一样的。一个很好的例子是各种集合类。获取此代码示例:

Interfaces are even more useful when you look at it from the other direction: they allow you to treat many different types as if they were all the same. A good example of this is with the various collections classes. Take this code sample:

void OutputValues(string[] values)
{
   foreach (string value in values)
   {
       Console.Writeline(value);
   }
}

这接受一个数组并将其输出到控制台。现在应用这个简单的更改来使用接口:

This accepts an array and outputs it to the console. Now apply this simple change to use an interface:

void OutputValues(IEnumerable<string> values)
{
   foreach (string value in values)
   {
       Console.Writeline(value);
   }
}

此代码仍然需要一个数组并将其输出到控制台。但它还需要一个 List< string> 或其他任何你需要的东西来实现 IEnumerable< string> 。所以我们采用了一个接口并用它来创建一个简单的代码块很多更强大。

This code still takes an array and outputs it to the console. But it also takes a List<string> or anything else you care to give it that implements IEnumerable<string>. So we've taken an interface and used it to make a simple block of code much more powerful.

另一个很好的例子是ASP。网络会员提供商。您告诉ASP.Net您通过实现所需的接口来履行成员资格合同。现在,您可以轻松自定义内置的ASP.Net身份验证以使用任何源,这一切都归功于接口。 System.Data命名空间中的数据提供程序以类似的方式工作。

Another good example is the ASP.Net membership provider. You tell ASP.Net that you honor the membership contract by implementing the required interfaces. Now you can easily customize the built-in ASP.Net authentication to use any source, and all thanks to interfaces. The data providers in the System.Data namespace work in a similar fashion.

最后一点:当我看到一个带有默认包装器实现的接口时,我认为它有点像anit-pattern,或者至少是代码味道。它向我表明,可能界面太复杂了,你要么需要拆分它,要么考虑使用组合+事件+委托的一些组合而不是派生来完成同样的事情。

One final note: when I see an interface with a "default" wrapper implementation like that, I consider it a bit of an anit-pattern, or at least a code smell. It indicates to me that maybe the interface is too complicated, and you either need to split it apart or consider using some combination of composition + events + delegates rather than derivation to accomplish the same thing.

这篇关于了解接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆