СЕКРЕТЫ И УЛОВКИ

Опасности использования необязательных параметров в .NET C#

Когда следует соблюдать осторожность при использовании необязательных параметров в .NET C#

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

Однако есть кое-что важное, о чем нужно помнить при использовании Необязательных параметров, особенно если вы разрабатываете собственную библиотеку классов.

В этой статье я покажу вам то, что может поразить вас.



Логические

Давайте сначала покажем вам проблему на примере.

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

Вместо создания собственной математической библиотеки вы решили использовать известную стороннюю библиотеку. Хороший выбор.

Теперь, для демонстрации, мы бы сами написали библиотеку и сохранили ее в том же решении. Однако в реальной жизни ожидается, что вы не являетесь владельцем библиотеки, и она может поставляться в виде пакета Nuget или даже в виде DLL для ссылки в вашем проекте.

Итак, начиная с этого момента, мы создадим наше решение, как на изображении ниже:

В проекте ThirdPartyLibrary у нас есть только один класс; класс Calculator.

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

using System;

namespace ThirdPartyLibrary
{
    public static class Calculator
    {
        public static int Add(int a = 0, int b = 0)
        {
            Console.WriteLine($"Add => a: {a}, b: {b}");
            return a + b;
        }

        public static int Multiply(int a, int b = 0)
        {
            Console.WriteLine($"Multiply => a: {a}, b: {b}");
            return a * b;
        }
    }
}

Как вы можете заметить, у нас есть два простых метода с некоторыми необязательными параметрами.

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

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

В проекте есть только один класс, который является классом Program.

Код внутри этого класса выглядит следующим образом:

using System;
using ThirdPartyLibrary;

namespace OptionalParameters
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int additionResult = Calculator.Add();
            additionResult = Calculator.Add(2);
            additionResult = Calculator.Add(2, 3);

            int multiplicationResult = Calculator.Multiply(2);
            multiplicationResult = Calculator.Multiply(2, 4);

            Console.ReadLine();
        }
    }
}

Видите, мы просто используем два метода внутри класса Calculator, но с разными значениями параметров.

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

Теперь давайте построим все решение и просмотрим каталог \OptionalParameters\bin\Debug.

Вы заметите, что скопированная ThirdPartyLibrary.dll является самой последней. Вы можете убедиться в этом, изучив столбец «Дата изменения», как показано на изображении ниже.

Теперь давайте запустим приложение, дважды щелкнув файл OptionalParameters.exe. Мы бы получили следующий результат:

Как и ожидалось, верно?

Теперь давайте внесем небольшое изменение в класс Calculator. Мы бы изменили значения по умолчанию для необязательных параметров на 10 вместо 0.

Итак, код будет следующим:

using System;

namespace ThirdPartyLibrary
{
    public static class Calculator
    {
        public static int Add(int a = 0, int b = 10)
        {
            Console.WriteLine($"Add => a: {a}, b: {b}");
            return a + b;
        }

        public static int Multiply(int a, int b = 10)
        {
            Console.WriteLine($"Multiply => a: {a}, b: {b}");
            return a * b;
        }
    }
}

Теперь из VS щелкните правой кнопкой мыши проект ThirdPartyLibrary и выберите Build.

Когда вы просматриваете каталог \OptionalParameters\bin\Debug, вы заметите, что скопированная туда ThirdPartyLibrary.dll не является последней. Вы можете убедиться в этом, изучив столбец «Дата изменения».

Чтобы исправить это, давайте просмотрим каталог \ThirdPartyLibrary\bin\Debug и скопируем файлы ThirdPartyLibrary.dll и ThirdPartyLibrary.pdb в каталог \OptionalParameters\bin\Debug. Теперь это последний.

Теперь давайте запустим приложение, дважды щелкнув файл OptionalParameters.exe. Мы бы получили следующий результат:

Я слышу, как ты сейчас кричишь:

Какого черта?!!!! Почему значения по умолчанию все еще 0, когда мы уже изменили их на 10? Разве мы не создали проект ThirdPartyLibrary?!!! Разве мы не скопировали последние файлы DLL?!!!

Да, мы построили проект ThirdPartyLibrary и скопировали последние файлы DLL. Однако этого недостаточно. Позвольте мне объяснить это вам.

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

Давайте построим все решение и запустим наш проект OptionalParameters, но не из самого VS. Давайте сделаем это, перейдя в каталог \OptionalParameters\bin\Debug и дважды щелкнув файл OptionalParameters.exe.

Сделав это, мы бы получили следующий результат:

Смотрите, это результат, которого мы действительно ожидали в прошлый раз.

Однако, почему это не сработало в прошлый раз, а теперь работает?

Позвольте мне сказать вам…

Улов

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

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

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

Последние мысли

В этой статье я объяснил опасность использования Необязательных параметров, о которых вам нужно помнить.

Вы можете спросить:

Но как избежать такого? Иногда мне действительно нужно использовать Необязательные параметры?

Мой ответ будет:

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

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

Надеюсь, вы нашли этот контент полезным. Если вы хотите поддержать:

▶ Если вы еще не являетесь участником Medium, вы можете использовать мою реферальную ссылку, чтобы я мог получать часть ваших сборов от Medium. > вы ничего не платите.
▶ Подпишитесь на мою рассылку новостей, чтобы получать рекомендации, руководства, подсказки, подсказки и многое другое прямо на ваш почтовый ящик.

Другие источники

Это другие ресурсы, которые могут оказаться полезными.











Повышение уровня кодирования

Спасибо, что являетесь частью нашего сообщества! Перед тем, как ты уйдешь:

  • 👏 Хлопайте за историю и подписывайтесь на автора 👉
  • 📰 Смотрите больше контента в публикации Level Up Coding
  • 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"

🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу