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

Я создал функцию для одновременной установки нескольких свойств объекта. Если определенный аргумент не передается функции, я хочу избежать его установки/изменения. Упрощенный пример самого чистого решения, которое я мог придумать, таков:

private void setObjectProperties(MyObject myObject, float param1, bool? param2 = null)
{
    myObject.param1 = param1;
    myObject.param2 = param2 != null ? (bool)param2 : myObject.param2;
}

Как видно из этого метода, если функция вызывается без передачи param2, она просто установит myObject.param2 в себя. (это означает, что если в param2 ничего не передается, то свойство myObject.param2 остается нетронутым)

То, что у меня есть, кажется мне немного грязным. Я не уверен, что это "правильный" поступок. Я думал о перегрузке методов, но подумал, что это будет еще более запутанно; В реальной ситуации я передаю более двух аргументов для установки, поэтому я могу получить много перегрузок.

Мне не хватает какой-то очевидной функциональности в С#, которая позволяет мне сказать: «Не устанавливайте этот параметр, если ему ничего не передается в соответствующий аргумент»?


person Danny Herbert    schedule 02.05.2016    source источник
comment
Почему тогда существует перегрузка методов? Я бы оставил его стандартным, чтобы любой, кто смотрит на код, знал, что происходит.   -  person Khalil Khalaf    schedule 03.05.2016
comment
@FirstStep Если бы было 5 свойств, вам потребовалось бы 32 перегрузки, чтобы охватить все случаи.   -  person Rob    schedule 03.05.2016
comment
разве это не 1 или 2 или 3 или 4 или 5? @роб   -  person Khalil Khalaf    schedule 03.05.2016
comment
@FirstStep Нет, потому что вы можете установить: [не 1, не 2], [1, не 2], [не 1, 2], [1, 2] и так далее для 2 свойств.   -  person Rob    schedule 03.05.2016
comment
Что произойдет, если пользователь захочет передать null? Это действительное значение во многих случаях. При этом нет, нет хорошего способа сделать это без кучи условных операторов. Будь то обычные операторы if или то, что у вас есть.   -  person Rob    schedule 03.05.2016
comment
@Rob Похоже, что свойство не может быть обнулено, поэтому не было бы способа установить для него значение null. Это не указано явно, но подразумевается приведением к bool.   -  person D Stanley    schedule 03.05.2016
comment
@DStanley да, свойство не может быть обнулено. Я думаю, что ваш ответ - мой лучший выбор. Позор, я надеялся, что какой-нибудь ловкий оператор спасет положение!   -  person Danny Herbert    schedule 03.05.2016
comment
Вы хотите, чтобы ваш код делал две разные вещи в зависимости от значения логического условия. Рассмотрите возможность использования оператора if в такой ситуации.   -  person Eric Lippert    schedule 03.05.2016


Ответы (3)


Мне не хватает какой-то очевидной функциональности в С#, которая позволяет мне сказать: «Не устанавливайте этот параметр, если ему ничего не передается в соответствующий аргумент»?

Не в ловком операторе, но, очевидно, вы можете сделать

if(param2.HasValue) myObject.param2 = (bool)param2;

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

person D Stanley    schedule 02.05.2016

Попробуйте использовать оператор объединения с нулевым значением ??:

private void setObjectProperties(MyObject myObject, float param1, bool? param2 = null, bool? param3 = null)
{
    myObject.param1 = param1;
    myObject.param2 = param2 ?? myObject.param2;
    myObject.param3 = param3 ?? myObject.param3;
}

который вы можете вызывать как

foo.setObjectProperties(myobj, param1,
       param2: p2, 
       param3: p3);
person AGB    schedule 02.05.2016

Сделай это так:

private void setObjectProperties(float? param1 = null, bool? param2 = null)
{
    if (param1.HasValue) {
      this.param1 = param1.Value;
    }
    if (param2.HasValue) {
      this.param2 = param2.Value;
    }
}

Потом:

MyObject myObject = new MyObject(); 
myObject.setObjectProperties(param1: 1.2f);
myObject.setObjectProperties(param2: true);
myObject.setObjectProperties(param1: 1.2f, param2: true);
person SyntaxGoonoo    schedule 02.05.2016