Непонимание 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()
потому что ты все еще нуждаешься в этом. И если вы забудете, отклоните или что-то еще, но ничего не напишите в нем, ваш потребитель класса в момент использования этого метода получит это исключение.
Абсолютно правильное поведение.