Есть ли причина объявлять необязательные параметры в интерфейсе?
Вы можете объявлять необязательные параметры в методе интерфейса, но для реализации классов не требуется объявлять параметры как необязательные, как объяснил Эрик Липперт. И наоборот, вы можете объявить параметр как необязательный в классе реализации, но не в интерфейсе.
Так есть ли какая-нибудь причина для объявления необязательных параметров в интерфейсе? Если нет, то почему это разрешено?
Примеры:
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) { }
}
Ответы
Ответ 1
Пример:
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");
Второй параметр, переданный в MyService1a
, будет true
, как параметр по умолчанию в интерфейсе.
Ответ 2
Причиной для этого было бы облегчить использование вызывающих абонентов, если у них есть тип времени компиляции - это просто интерфейс:
public void Foo(IService1 service)
{
service.MyMethod("Text"); // Calls MyMethod("Text", false)
}
Достаточно часто для вызывающего только знать о интерфейсе что-то реализует, а не конкретный тип - поэтому, если вы считаете, что необязательные параметры - это хорошая идея (это противоречиво), это имеет смысл иметь их на интерфейсах, поскольку на конкретных типах.
Ответ 3
Если вы проектируете интерфейс с методом Foo
, который принимает параметр Bar
, а 99% (но не 100%) вызовов Foo
передают ноль для Bar
, необходимо либо:
- Включить в перегрузку метода интерфейса, которые включают и не включают параметр `Bar`, тем самым требуя, чтобы каждая реализация этого интерфейса включала дополнительный метод, но освобождала вызывающих абонентов от необходимости указывать его.
- Включить только метод, который включает в себя "Бар", чтобы сохранить реализаторы стоимости дополнительного метода, но требуя, чтобы дополнительный параметр включался на каждый сайт вызова.
- Определите параметр как необязательный в интерфейсе, что сделает вещи более удобными как для разработчиков, так и для потребителей.
Вариант № 3 кажется мне наиболее удобным, когда он работоспособен.
Ответ 4
Полезно, что интерфейс может объявлять их так, как он хочет, поэтому вы получаете точную гибкость, которую вы хотели бы при создании интерфейса. Другими словами, разработчик в производном классе может сделать параметр необязательным, может потребовать его и т.д. По желанию. Если он не является обязательным, производные классы должны иметь его.
В приведенном выше примере показан только тот факт - гибкость в производных классах.
Ответ 5
Представление конструктора интерфейса по умолчанию может отличаться от дизайна конструктора.
Параметры по умолчанию просто расширяются компилятором, а параметры заменяются фактическими значениями по умолчанию.
Когда вы вызываете метод объекта, являющегося экземпляром интерфейса, компилятор заменит значения по умолчанию, указанные на интерфейсе.
И когда вы вызываете метод для объекта, являющегося экземпляром класса, компилятор заменит значения по умолчанию, указанные в классе.