Есть ли причина объявлять необязательные параметры в интерфейсе? - PullRequest
21 голосов
/ 19 июля 2011

Вы можете объявить необязательные параметры в методе интерфейса, но реализации классов не требуется для объявления параметров как необязательных, как объяснил Эрик Липперт . И наоборот, вы можете объявить параметр как необязательный в реализующем классе, но не в интерфейсе.

Так есть ли причина объявлять необязательные параметры в интерфейсе? Если нет, то почему это разрешено?

Примеры:

public interface IService1
{
    void MyMethod(string text, bool flag = false);
}

public class MyService1a : IService1
{
    public void MyMethod(string text, bool flag) {}
}

public class MyService1b : IService1
{
    public void MyMethod(string text, bool flag = true) { }
}

public interface IService2
{
    void MyMethod(string text, bool flag);
}

public class MyService2b : IService2
{
    public void MyMethod(string text, bool flag = false) { }
}

Ответы [ 5 ]

22 голосов
/ 19 июля 2011

Пример:

public interface IService1
{
    void MyMethod(string text, bool flag = true);
}

public class MyService1a : IService1
{
    public void MyMethod(string text, bool flag) { }
}

Использование:

IService1 ser = new MyService1a();
ser.MyMethod("A");

2-й параметр, переданный MyService1a, будет true, как параметр по умолчанию в интерфейсе.

20 голосов
/ 19 июля 2011

Причиной для этого будет упрощение использования вызывающими программами, когда тип времени компиляции, который у них есть, является просто интерфейсом:

public void Foo(IService1 service)
{
    service.MyMethod("Text"); // Calls MyMethod("Text", false)
}

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

3 голосов
/ 20 октября 2012

Если проектируется интерфейс с методом Foo, который принимает параметр Bar, и 99% (но не 100%) вызовов Foo проходят ноль для Bar, необходимо либо:

  1. Включение в интерфейс перегрузки метода, которые включают и не включают параметр `Bar`, что требует от каждой реализации этого интерфейса включения дополнительного метода, но освобождает вызывающих абонентов от необходимости его указывать.
  2. Включает только метод, который включает `Bar`, сохраняя реализаторам стоимость дополнительного метода, но требуя, чтобы дополнительный параметр был включен на каждом сайте вызова.
  3. Определяет параметр как необязательный в интерфейсе, что делает его более удобным как для разработчиков, так и для потребителей.

Вариант № 3 кажется мне наиболее удобным, когда он работает.

1 голос
/ 19 июля 2011

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

Ваш приведенный выше пример демонстрирует гибкость производных классов.

0 голосов
/ 19 июля 2011

Предположение дизайнера интерфейса о параметрах по умолчанию может отличаться от проекта разработчика.

Параметры по умолчанию просто расширяются компилятором, а параметры заменяются фактическими значениями по умолчанию.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...