Конструктор без параметров для сериализации в сочетании с конструктором, который имеет параметр по умолчанию, почему он работает? - PullRequest
3 голосов
/ 23 ноября 2011

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

[Serializable]
public class TestClass
{
    public int Variable;
}

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

[Serializable]
public class TestClass
{
    public int Variable;

    private TestClass() {}

    public TestClass(int value)
    {
        Variable = value;
    }     
}

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

[Serializable]
public class TestClass
{
    public int Variable;

    private TestClass() {}

    public TestClass(int value = 0)
    {
        Variable = value;
    }     
}

И все это прекрасно работает, но почему? Разве у нас нет двух конструкторов с одинаковым определением? Даже если я сделаю конструктор по умолчанию общедоступным, все работает нормально. Как только я удаляю конструктор по умолчанию, он терпит неудачу при сериализации. Мое первое предположение состоит в том, что XmlSerialize .NET не проверяет конструкторы с параметрами по умолчанию. Но почему компилятор все еще разрешает этот код?

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

1 Ответ

5 голосов
/ 23 ноября 2011

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

Разрешение перегрузки в конструкторе без параметров по сравнению с конструктором, имеющим толькоАргументы по умолчанию (или любой метод в той же ситуации) сводятся к специфике.Среди множества других правил разрешения перегрузки спецификация языка C # 4.0 (7.5.3.2 лучший член функции) гласит:

В противном случае, если все параметры MP имеют соответствующий аргумент, тогда как аргументы по умолчанию необходимо заменитьхотя бы для одного необязательного параметра в MQ значение MP лучше, чем MQ.

Из этой информации мы можем упростить и задать вопрос о ваших конструкторах.Когда вы говорите new TestClass(), кого выбрать?

  1. Мы указали все аргументы, которые мы хотели бы передать вызову.В этом случае это ноль.

  2. Есть ли конструктор с точно нулевыми аргументами, который виден вызывающему абоненту?

  3. Если это так, вызовитеит.

  4. Если нет, назовите следующую лучшую вещь.В этом случае ваш конструктор имеет аргументы по умолчанию.

Обратите внимание, что XmlSerializer не соответствует этим правилам .Он точно знает, чего хочет, и будет жаловаться, если вы его не предоставите.

...