Непонимание API с использованием интерфейсов

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

public partial class Form1 : Form, IFoo
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Guid jobID = AddBarToFoo(fooID, barPath);
    }

    public Guid IFoo.AddBarToFoo(string fooID, string barPath)
    {
        throw new NotImplementedException();
    }

Так что это основная структура. Visual Studio любезно реализовал интерфейс полностью, и я могу вызвать метод AddBarToFoo. Отлично.

Но что теперь? Очевидно, что метод является пустотой, которая требует некоторого кода, но какой код? Должен ли я обыскивать API для объектов, чтобы создать экземпляр этого метода? Или я иду по неверному пути?

2 ответа

Решение

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

VS "реализует" метод, добавляя одну строку throw new NotImplementedException(); что на самом деле просто для удовлетворения компилятора.

Вот две возможные (надуманные) реализации, которые делают совершенно разные вещи. Оба реализуют IFoo:

public class DbFoo:IFoo {
    public Guid IFoo.AddBarToFoo(string fooID, string barPath) {
        // this might add a Foo to the database and return its Guid
    }
}

public class ListBasedFoo:IFoo {
    public ListBasedFoo() { MyList = new List<Foo>(); }

    public List<Foo> MyList { get; private set; }

    public Guid IFoo.AddBarToFoo(string fooID, string barPath) {
        // this could add a Foo to MyList, and return some Guid to reference it
    }
}

Редактировать... Вы увидите, что интерфейсы часто используются в местах, где важно абстрактное поведение, но реализация может отличаться. Например, интерфейс для сохранения объектов. Во время разработки вы можете использовать макет, который помещает и помещает элементы в список в памяти. Позже вы можете использовать интерфейс, который напрямую обращается к базе данных через ADO .NET или Entity Framework или LINQ to SQL. Возможно, в другой момент жизни приложения будет добавлена ​​новая реализация, которая вместо этого использует веб-службы WCF.

Дело в моем примере выше, что вызывающий код не сломается. Интерфейс доволен - изменилось только поведение.

Interface это контракт, который вы собираетесь подписать, в момент его реализации. То, что вы должны делать в этом методе, зависит от того, что вы собираетесь делать с этим интерфейсом.

public class MyFooImplementation:IFoo {
    public Guid IFoo.AddBarToFoo(string fooID, string barPath) {
        // do somethign and return GUID
    }
}

Visual Studio любезно генерирует для вас метод с необходимой подписью, но, естественно, запихивает NotImplementedException()потому что ты все еще нуждаешься в этом. И если вы забудете, отклоните или что-то еще, но ничего не напишите в нем, ваш потребитель класса в момент использования этого метода получит это исключение.

Абсолютно правильное поведение.

Другие вопросы по тегам