c# – 需要帮助了解接口

我仍然无法理解什么接口是有益的。我读了几个教程,我仍然不知道他们真正的是什么,然后“他们让你的课程保持承诺”和“他们帮助多重继承”。

关于它我仍然不知道什么时候甚至会在实际的工作示例中使用界面,甚至何时识别何时使用它。

从我有限的界面知识,他们可以帮助,因为如果有一些实现它,那么你可以通过界面允许传入像不同的类,而不用担心它不是正确的参数。

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

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

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

ICalculator myInterface = new JustSomeClass();

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

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

例如这个例子:

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;
}

为什么打扰这个界面?为什么不使FormAuthenticationWrapper与其中的方法并称之为一天?为什么首先使一个接口让Wrapper实现接口,然后最后编写方法?

那么我没有得到什么声明真的说。

就像我知道这个说法是这样的

FormsAuth = formsAuth?新FormsAuthenticationWrapper();

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

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

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

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

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

但是看新的Mock(从moq)它接受一个类或接口。为什么不再让包装类把这些方法放入,然后在新的Mock调用呢?

这不是只为你的存根吗?

谢谢

最佳答案
接口定义合同。

在你提供的例子中,如果将null传递给构造函数,并且与接口没有任何关系,则运算符只提供一个默认值。

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

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

当您从另一个方向看时,界面更为有用:它们允许您将许多不同的类型视为完全一样。一个很好的例子就是使用各种集合类。拿这个代码示例:

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

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

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

此代码仍然需要一个数组并将其输出到控制台。但它也需要一个列表< string>或者你想要的任何其他东西来实现IEnumerable< string>。所以我们采取了一个界面,并使用它来使一个简单的代码块更强大。

另一个很好的例子是ASP.Net会员提供商。你告诉ASP.Net你通过实现所需的接口来遵守会员合同。现在,您可以轻松地自定义内置的ASP.Net身份验证以使用任何来源,并且都感谢接口。 System.Data命名空间中的数据提供者的工作方式类似。

最后一个注意事项:当我看到有一个这样的“默认”包装器实现的接口时,我认为它有点anit模式,或至少一个代码的气味。它告诉我,也许界面太复杂了,你需要将它分开,或考虑使用组合事件代理的组合而不是派生来完成同样的事情。

转载注明原文:c# – 需要帮助了解接口 - 代码日志