2013-02-26 3 views
1

Я работаю с C# и .NET в течение некоторого времени и даже несмотря на то, что раньше я работал с языками OOP (точнее, Java), работая над приложениями .NET Я вижу, что интерфейсы использовались намного больше, чем я видел на Java. У меня нет большого опыта, поэтому я не говорю, что интерфейсы больше используются в .NET, но теперь я почувствовал необходимость более глубокого понимания интерфейсов и каковы преимущества, которые заставляют людей использовать их так часто ,Объяснение использования интерфейса (перспектива C#)

У меня есть кое-что в интернете, кое-что здесь, и объяснение, которое имело для меня наибольшее значение, было следующим: How will I know when to create an interface?.

И вот мой вопрос. Я не ожидаю какого-либо магического объяснения интерфейсов вообще, потому что я достаточно читал, чтобы увидеть, что этого не происходит. Я надеюсь, что с опытом и кодированием более глубокое понимание придет само собой, поэтому я решил попробовать пример, обозначенный как преимущество использования интерфейсов из принятого ответа в ссылке. Я также скопирую его здесь:

У вас есть a, b, c, d из 4 разных типов. всего кода у вас есть что-то вроде:

a.Process(); 
b.Process(); 
c.Process(); 
d.Process(); 

Почему бы не иметь их реализации IProcessable, а затем сделать

List<IProcessable> list; 

foreach(IProcessable p in list) 
    p.Process(); 

Этот масштабируется намного лучше, когда вы добавляете, скажем, 50 типов классов, которые все делайте то же самое.

Проблема в том, что, похоже, у меня этого нет. После того, как я прочитал его, я открыл свою Visual Studio 2010 и попытался воссоздать этот пример: я сделал проект и создал четыре класса: a, b, c, d. Все эти классы одинаковы:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class a : ITest 
    { 
     public void Test() 
     { 
      System.Console.WriteLine("Hi from a"); 
     } 
    } 
} 

всего 4 различных имена и метод Test() печати имени. Вот интерфейс:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    interface ITest 
    { 
     public void Test(); 
    } 
} 

И то, что я понимаю в моем Program.cs у меня есть это:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     List<ITest> list; 
     static void Main(string[] args) 
     { 
      foreach (ITest p in list) 
       p.Test(); 
     } 
    } 
} 

Хорошо. Кажется, что я действительно ошибался. Я думал, что, реализуя один и тот же интерфейс, я могу автоматически получить список всех классов и использовать их, например, как в моем методе Main() выше. Однако я получаю следующее сообщение об ошибке:

An object reference is required for the non-static field, method, or property

Ну, кто-то может понизить уровень мне и объяснить мне, с точки зрения этого примера, как я точно принести пользу, как это с помощью интерфейса.

+3

Интерфейсы здесь не проблема - это поле 'list'' Program'. Это должно быть статическое поле, чтобы использовать его из статического метода 'Main'. (Вероятно, вы также захотите добавить некоторые вещи в этот список) – kevingessner

+1

Это будет хорошее чтение - http://stackoverflow.com/q/14482483/218882 –

ответ

1

Ваш код выглядит хорошо с точки зрения создания классов, будет реализовывать интерфейс. Кажется, что проблема заключается в вашей инициализации.

Как вы заявляете, List<ITest> list не является статическим полем. Функция Main является статическим методом, поэтому она может обращаться только к другим статическим полям.

Если вы хотите, чтобы продолжить основной пример, попробуйте установить list как статическое поле, или в качестве переменной в Main и инстанцировании его, населяющих его с некоторыми объектами, прежде чем использовать его в foreach цикле.

3

Проблема здесь не имеет ничего общего с интерфейсом, но с классом Program. Поле list является членом экземпляра, тогда как метод Main является статическим. Как указано в исключении, вы не можете ссылаться на нестатические элементы из статических методов.

Кроме того, list не был создан или не инициализирован (по крайней мере, не в том фрагменте, который вы опубликовали). Так что даже list, если был объявлен как статический, ваш код произвел бы NullReferenceException.

Попробуйте изменить Program класс к этому:

class Program 
{ 
    static List<ITest> list; 
    static void Main(string[] args) 
    { 
     list = new List<ITest>(); 
     // ... 
     // initialize list 
     // ... 

     foreach (ITest p in list) 
      p.Test(); 
    } 
} 
1

Что касается вашей ошибки, это выглядит как list не экземпляр, и это поле экземпляра, к которому имеют доступ статического метода.


Интерфейсы не предназначены для наследования, они предназначены для полиморфизма.

Интерфейс не предназначен для сохранения кода. Если вам нужно это сделать, используйте абстрактные классы.

Весь интерфейс делает это гарантией для компилятора, что ваш класс будет вести себя определенным образом. В нем ничего не говорится о реализации.

Например, у вас есть и List и LinkedList являются implimented по-разному, но оба они соответствуют интерфейсу IEnumberable и, следовательно, может повторяться в течение в петле foreach

0

Использование интерфейса определяет что-то вроде заполнителя для объекта, который определенно будет иметь определенное поведение, не зная об этом. Например, вы можете иметь класс A и класс B, оба из них реализуют IMyInterface. Если вам нужен экземпляр IMyInterface, вы можете использовать оба из них и вызывать метод, указанный в интерфейсе, но реализованный в A или B. Также существует большое использование интерфейсов в контейнерах IoC на основе конвенций.

Смежные вопросы