Неоднозначность с наследованием метода с необязательным параметром - PullRequest
4 голосов
/ 19 сентября 2011

У меня есть базовый класс с одним необязательным параметром по умолчанию, который дочерний класс автоматически предоставляет значение для:

public class Merchant
{
    public string WriteResults(List<string> moreFields = null)
    {

        List<string> ListOfObjects = new List<string>() {Name, Address};
        if (moreFields != null)
        {
            ListOfObjects.AddRange(moreFields);
        }
            return ListOfObjects.ToString() //not real output
}


public class SpecificMerchant : Merchant 
{   
    new public string WriteResults()
        {
            return ((Merchant)this).WriteResults(new List<string>() {
                    Address, Phone //class-specific parameters
            });
        }
}

Я использовал ключевое слово new при вызове SpecificMerchant.WriteResults, поскольку и родитель, и база не могут принимать параметры, но компилятор говорит, что это не нужно:

Член 'SpecificMerchant.WriteResults ()' не скрывает унаследованный член. Новое ключевое слово не требуется.

Почему? Разве я на практике не переопределяю родительский метод?

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

Нет, вы не переопределите это.Вы предоставляете метод с другой подписью.Учтите это:

new SpecificMerchant().WriteResults(new List<string>());

Может ли возможно вызвать метод в SpecificMerchant?Нет - вы указали аргумент, а SpecificMerchant.WriteResults не указывает никаких параметров.Уже один этот факт показывает, что он не может переопределить Merchant.WriteResults.

Ваш код, безусловно, может вызвать путаницу, поскольку перегрузка в иерархии типов часто делает даже без необязательных параметров - но насколькочто касается компилятора C # и CLR, то это очень разные методы ... Случается, что оба будут валидными для вызова без заданных аргументов, но это другой вопрос.

1 голос
/ 19 сентября 2011

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

Ваш базовый класс всегда будет иметь метод с одним параметром. Компилятор просто «подставляет» null во время компиляции , если вы вызываете этот метод без аргумента.

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

Для хорошего ресурса я бы порекомендовал прочитать Пост Джеймса Майкла Хэра о необязательных параметрах - Он обсуждает подводные камни, подобные этому, когда вы смешиваете необязательные аргументы с наследованием.

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