C# 使用接口变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2151959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:57:26  来源:igfitidea点击:

Using Interface variables

c#

提问by PositiveGuy

I'm still trying to get a better understanding of Interfaces. I know about what they are and how to implement them in classes.

我仍在努力更好地了解接口。我知道它们是什么以及如何在课堂上实现它们。

What I don't understand is when you create a variable that is of one of your Interface types:

我不明白的是,当您创建属于您的接口类型之一的变量时:

IMyInterface somevariable;

Why would you do this? I don't understand how IMyInterface can be used like a class...for example to call methods, so:

你为什么要这样做?我不明白 IMyInterface 如何像类一样使用......例如调用方法,所以:

somevariable.CallSomeMethod();

Why would you use an IMyInterface variable to do this?

为什么要使用 IMyInterface 变量来执行此操作?

采纳答案by David Hall

You are not creating an instance of the interface - you are creating an instance of something that implements the interface.

您不是在创建接口的实例 - 您正在创建实现接口的东西的实例。

The point of the interface is that it guarantees that what ever implements it will provide the methods declared within it.

接口的重点是它保证实现它的任何东西都将提供在其中声明的方法。

So now, using your example, you could have:

所以现在,使用您的示例,您可以:

MyNiftyClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something nifty
    }
}

MyOddClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something odd
    }
}

And now you have:

现在你有:

IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()

Calling the CallSomeMethod method will now do either something nifty or something odd, and this becomes particulary useful when you are passing in using IMyInterface as the type.

调用 CallSomeMethod 方法现在可以做一些漂亮或奇怪的事情,当您使用 IMyInterface 作为类型传入时,这变得特别有用。

public void ThisMethodShowsHowItWorks(IMyInterface someObject)
{
    someObject.CallSomeMethod();
}

Now, depending on whether you call the above method with a nifty or an odd class, you get different behaviour.

现在,根据您是使用漂亮的类还是奇怪的类调用上述方法,您会得到不同的行为。

public void AnotherClass()
{
    IMyInterface nifty = new MyNiftyClass()
    IMyInterface odd = new MyOddClass()

    // Pass in the nifty class to do something nifty
    this.ThisMethodShowsHowItWorks(nifty);

    // Pass in the odd class to do something odd
    this.ThisMethodShowsHowItWorks(odd);

}

EDIT

编辑

This addresses what I think your intended question is - Why would you declare a variable to be of an interface type?

这解决了我认为您想要解决的问题 - 为什么要将变量声明为接口类型?

That is, why use:

也就是说,为什么使用:

IMyInterface foo = new MyConcreteClass();

in preference to:

优先于:

MyConcreteClass foo = new MyConcreteClass();

Hopefully it is clear why you would use the interface when declaring a method signature, but that leaves the question about locally scoped variables:

希望您在声明方法签名时清楚为什么要使用该接口,但这留下了有关局部范围变量的问题:

public void AMethod()
{
    // Why use this?
    IMyInterface foo = new MyConcreteClass();

    // Why not use this?
    MyConcreteClass bar = new MyConcreteClass();
}

Usually there is no technical reason why the interface is preferred. I usually use the interface because:

通常没有技术原因为什么该接口是首选的。我通常使用该接口是因为:

  • I typically inject dependencies so the polymorphism is needed
  • Using the interface clearly states my intent to only use members of the interface
  • 我通常会注入依赖项,因此需要多态性
  • 使用界面清楚地表明我只使用界面成员的意图

The one place where you would technicallyneed the interface is where you are utilising the polymorphism, such as creating your variable using a factory or (as I say above) using dependency injection.

您在技术上需要接口的地方是您使用多态性的地方,例如使用工厂创建变量或(如我上面所说)使用依赖注入。

Borrowing an example from itowlson, using concrete declaration you could not do this:

借用 itowlson 的一个例子,使用具体的声明你不能这样做:

public void AMethod(string input)
{               
    IMyInterface foo;

    if (input == "nifty")
    {
        foo = new MyNiftyClass();
    }
    else
    {
        foo = new MyOddClass();
    }
    foo.CallSomeMethod();
}

回答by Amirshk

The purpose of the Interface is to define a contract between several objects, independent of specific implementation.

接口的目的是定义几个对象之间的契约,独立于具体的实现。

So you would usually use it when you have an Intrace ISomething, and a specific implementation

所以当你有一个 IntraceISomething和一个特定的实现时,你通常会使用它

class Something : ISomething

So the Interface varialbe would come to use when you instantiate a contract:

因此,当您实例化合约时,将使用 Interface varialbe:

ISomething myObj = new Something();
myObj.SomeFunc();

You should also read interface C#

您还应该阅读接口 C#

Update:

更新:

I will explaing the logic of using an Interface for the variable and not the class itself by a (real life) example:

我将通过一个(现实生活中的)示例来解释为变量而不是类本身使用接口的逻辑:

I have a generic repositor interace:

我有一个通用的存储库接口:

Interface IRepository {
    void Create();
    void Update();
}

And i have 2 seperate implementations:

我有 2 个单独的实现:

class RepositoryFile : interface IRepository {}
class RepositoryDB : interface IRepository {}

Each class has an entirely different internal implementation.

每个类都有一个完全不同的内部实现。

Now i have another object, a Logger, that uses an already instansiated repository to do his writing. This object, doesn't care how the Repository is implemented, so he just implements:

现在我有另一个对象,一个 Logger,它使用一个已经实例化的存储库来完成他的写作。这个对象,并不关心 Repository 是如何实现的,所以他只是实现:

void WriteLog(string Log, IRepository oRep);

BTW, this can also be implemented by using standard classes inheritance. But the difference between using interfaces and classes inheritance is another discussion.

顺便说一句,这也可以通过使用标准类继承来实现。但是使用接口和类继承之间的区别是另一个讨论。

For a slightly more details discussion on the difference between abstract classes and interfaces see here.

有关抽象类和接口之间差异的详细讨论,请参见此处

回答by Aaron

Say, for example, you have two classes: Bookand Newspaper. You can read each of these, but it wouldn't really make sense for these two to inherit from a common superclass. So they will both implement the IReadableinterface:

例如,假设您有两个类:BookNewspaper。您可以阅读其中的每一个,但是这两个继承自一个共同的超类实际上没有意义。所以他们都将实现IReadable接口:

public interface IReadable
{
    public void Read();
}

Now say you're writing an application that will read books and newspapers for the user. The user can select a book or newspaper from a list, and that item will be read to the user.

现在假设您正在编写一个为用户阅读书籍和报纸的应用程序。用户可以从列表中选择一本书或报纸,然后将向用户朗读该项目。

The method in your application that reads to the user will take this Bookor Newspaperas a parameter. This might look like this in code:

应用程序中读取给用户的方法将使用 thisBookNewspaper作为参数。这在代码中可能如下所示:

public static void ReadItem(IReadable item)
{
    item.Read();
}

Since the parameter is an IReadable, we know that the object has the method Read(), thus we call it to read it to the user. It doesn't matter whether this is a Book, Newspaper, or anything else that implements IReadable. The individual classes implement exactly how each item will be read by implementing the Read()method, since it will most likely be different for the different classes.

由于参数是 an IReadable,我们知道对象有方法Read(),因此我们调用它来读取它给用户。不要紧,这是否是一个BookNewspaper或其他任何工具IReadable。各个类通过实现该Read()方法准确地实现了每个项目的读取方式,因为不同的类很可能会有所不同。

Book's Read()might look like this:

BookRead()可能是这样的:

public void Read()
{
    this.Open();
    this.TurnToPage(1);
    while(!this.AtLastPage)
    {
        ReadText(this.CurrentPage.Text);
        this.TurnPage();
    }
    this.Close();
}

Newspaper's Read()would likely be a little different:

Newspaper'sRead()可能会有所不同:

public void Read()
{
    while(!this.OnBackPage)
    {
        foreach(Article article in this.CurrentPage.Articles)
        {
            ReadText(article.Text);
        }
    }
}

The point is that the object contained by a variable that is an interface type is guaranteed to have a specific set of methods on it, even if the possible classes of the object are not related in any other way. This allows you to write code that will apply to a variety of classes that have common operations that can be performed on them.

关键是,接口类型的变量所包含的对象保证有一组特定的方法,即使对象的可能类没有任何其他关联。这使您可以编写适用于具有可以对其执行的通用操作的各种类的代码。

回答by ChaosPandion

Because this:

因为这:

public void ReadItemsList(List<string> items);
public void ReadItemsArray(string[] items);

can become this:

可以变成这样:

public void ReadItems(IEnumerable<string> items);

Edit

编辑

Think of it like this:

可以这样想:

You have to be able to do this.

你必须能够做到这一点。

rather than:

而不是:

You have to be this.

你必须是这个。

Essentially this is a contract between the method and it's callers.

本质上,这是方法与其调用者之间的契约。

回答by Jay

This is a fundamental concept in object-oriented programming -- polymorphism. (wikipedia)

这是面向对象编程中的一个基本概念——多态。(维基百科

The short answer is that by using the interface in Class A, you can give Class A any implementation of IMyInterface.

简短的回答是,通过使用一个类中的接口,你可以给A类的任何实现IMyInterface

This is also a form of loose coupling (wikipedia) -- where you have many classes, but they do not rely explicitly on one another -- only on an abstract notion of the set of properties and methods that they provide (the interface).

这也是一种松耦合(维基百科)的形式——你有很多类,但它们并不明确地相互依赖——只依赖于它们提供的一组属性和方法(接口)的抽象概念。

回答by Ravisha

This is not specific to C#,so i recommend to move to some othere flag. for your question, the main reason why we opt for interface is to provide a protocol between two components(can be a dll,jar or any othere component). Please refer below

这不是特定于 C# 的,所以我建议移到一些其他标志。对于您的问题,我们选择接口的主要原因是在两个组件(可以是 dll、jar 或任何其他组件)之间提供协议。请参考以下

 public class TestClass
    {
        static void Main()
        {
            IMyInterface ob1, obj2;
            ob1 = getIMyInterfaceObj();
            obj2 = getIMyInterfaceObj();
            Console.WriteLine(ob1.CallSomeMethod());
            Console.WriteLine(obj2.CallSomeMethod());
            Console.ReadLine();

        }

        private static bool isfirstTime = true;
        private static IMyInterface getIMyInterfaceObj()
        {
            if (isfirstTime)
            {
                isfirstTime = false;
                return new ImplementingClass1();
            }
            else
            {
                return new ImplementingClass2();
            }
        }
    }
    public class ImplementingClass1 : IMyInterface
    {
        public ImplementingClass1()
        {

        }


        #region IMyInterface Members

        public bool CallSomeMethod()
        {
            return true;
        }

        #endregion
    }

    public class ImplementingClass2 : IMyInterface
    {
        public ImplementingClass2()
        {

        }
        #region IMyInterface Members

        public bool CallSomeMethod()
        {
            return false;
        }

        #endregion
    }
    public interface IMyInterface
    {
        bool CallSomeMethod();

    }

Here the main method does not know about the classes still it is able to get different behaviour using the interface.

这里的主要方法不知道类,但它仍然能够使用接口获得不同的行为。

回答by PostMan

Lets say you have class Boat, Car, Truck, Plane.

假设您有类船、汽车、卡车、飞机。

These all share a common method TakeMeThere(string destination)

这些都共享一个通用方法 TakeMeThere(string destination)

You would have an interface:

你会有一个界面:

public interface ITransportation
{
    public void TakeMeThere(string destination);
}

then your class:

那么你的班级:

public class Boat : ITransportation
{
   public void TakeMeThere(string destination) // From ITransportation
   {
       Console.WriteLine("Going to " + destination);
   }
}

What you're saying here, is that my class Boatwill do everything ITransportationhas told me too.

你在这里说的是,我的班级也会做ITransportation告诉我的一切。

And then when you want to make software for a transport company. You could have a method

然后当您想为运输公司制作软件时。你可以有一个方法

Void ProvideServiceForClient(ITransportation transportationMethod, string whereTheyWantToGo)
{
      transportationMethod.TakeMeThere(whereTheyWantToGo); // Cause ITransportation has this method
}

So it doesn't matter which type of transportation they want, because we know it can TakeMeThere

所以他们想要哪种交通工具并不重要,因为我们知道它可以TakeMeThere

回答by Shane

An interface is used so you do not need to worry about what class implements the interface. An example of this being useful is when you have a factory method that returns a concrete implementation that may be different depending on the environment you are running in. It also allows an API designer to define the API while allowing 3rd parties to implement the API in any way they see fit. Sun does this with it's cryptographic API's for Java.

使用了接口,因此您无需担心实现该接口的类。一个有用的例子是当你有一个工厂方法返回一个具体的实现时,具体实现可能会根据你运行的环境而不同。它还允许 API 设计者定义 API,同时允许 3rd 方在他们认为合适的任何方式。Sun 使用它的 Java 加密 API 来做到这一点。

public interface Foo {

}

public class FooFactory {
    public static Foo getInstance() {
        if(os == 'Windows') return new WinFoo();
        else if(os == 'OS X') return new MacFoo();
        else return new GenricFoo();
    }
}

Your code that uses the factory only needs to know about Foo, not any of the specific implementations.

您使用工厂的代码只需要了解 Foo,而不需要任何特定的实现。

回答by NotMe

Using interface variables is the ONLY way to allow handler methods to be written which can accept data from objects that have different base classes.

使用接口变量是允许编写可以接受来自具有不同基类的对象的数据的处理程序方法的唯一方法。

This is about as clear as anyone is going to get.

这与任何人都会得到的一样清楚。

回答by Yogesh Yadav

No, it is not possible. Designers did not provide a way. Of course, it is of common sense also. Because interface contains only abstract methods and as abstract methods do not have a body (of implementation code), we cannot create an object..

不,这是不可能的。设计师没有提供方法。当然,这也是常识。因为接口只包含抽象方法并且抽象方法没有(实现代码的)主体,所以我们不能创建对象。

Suppose even if it is permitted, what is the use. Calling the abstract method with object does not yield any purpose as no output. No functionality to abstract methods. Then, what is the use of interfaces in Java design and coding. They can be used as prototypes from which you can develop new classes easily. They work like templates for other classes that implement interface just like a blue print to construct a building.

假设即使允许,又有什么用。使用对象调用抽象方法不会产生任何目的,因为没有输出。没有抽象方法的功能。那么,接口在Java设计和编码中的用途是什么。它们可以用作原型,您可以从中轻松开发新类。它们像其他类的模板一样工作,实现接口就像构建建筑物的蓝图。