Параметры по умолчанию в C # 4.0 - PullRequest
3 голосов
/ 14 ноября 2011

Рассмотрим следующее консольное приложение:

class Program
{
    static void Main()
    {
        MyInterface test = new MyClass();
        test.MyMethod();

        Console.ReadKey();
    }
}

interface MyInterface
{
    void MyMethod(string myString = "I am the default value on the interface");
}

class MyClass : MyInterface
{
    public void MyMethod(string myString = "I am the default value set on the implementing class")
    {
        Console.WriteLine(myString);
    }
}

Вывод этой программы:

I am the default value on the interface

(1) Почему нет способа указатьнеобязательный параметр в интерфейсе без указания значения. Я считаю значение по умолчанию подробным описанием реализации.Если бы мы написали этот код в стиле предварительно необязательного параметра, мы бы создали две перегрузки в интерфейсе, а значение по умолчанию было бы указано в реализующем классе.Т.е. у нас будет:

interface MyInterface
{
    void MyMethod();

    void MyMethod(string myString);
}

class MyClass : MyInterface
{
    public void MyMethod()
    {
        MyMethod("I am the default value set on the implementing class");
    }

    public void MyMethod(string myString)
    {
        Console.WriteLine(myString);
    }
}

Какие выходные данные, как мы и ожидаем,

I am the default value set on the implementing class

(2) Почему мы не можем переопределить значение по умолчанию в реализующем классе!

Ответы [ 2 ]

4 голосов
/ 14 ноября 2011

Значения по умолчанию в .Net являются синтаксическим сахаром, основанным на компиляторе. На сайте вызовов компилятор добавляет значения по умолчанию для вас. Он не может знать тип времени выполнения вашего объекта во время компиляции, поэтому он должен вставить значение, определенное в интерфейсе.

Следовательно, они не могут быть «переопределены» в реализациях, потому что нечего переопределять.

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

Обновление
Из ваших комментариев вы предлагаете либо некоторую форму «виртуального» параметра (в котором объявляется тип среды выполнения), о котором CLR должен был бы «знать». Я предполагаю, что эта реализация была исключена, потому что затраты (разработка, документирование, реализация, тестирование и т. Д.) Были слишком высоки по сравнению с преимуществами, которые она дала (хотя это только предположение!). В качестве альтернативы есть опция метода делегирования по умолчанию, например:

void M(bool y = false) { ... whatever ... }

Получает переписанный компилятором как:

void M() { M(false); }
void M(bool y) { ... whatever ... }

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

3 голосов
/ 14 ноября 2011

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

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

2) Поскольку интерфейс определяет операционнуюконтракт.Интерфейс говорит, что по умолчанию должно быть что-то ... поэтому класс должен реализовывать это таким образом.

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