02 ноября 2008

Новые возможности C# 4.0. Часть 2: параметры по умолчанию

Сегодня мы поговорим о другой новинке C# 4.0, которую я ждал много лет. В прошлом, ее отсутствие объяснялось архитектурным решением. Но, видимо, прагматизм победил и теперь у нас есть параметры по умолчанию. Чтобы сделать их еще более полезными они добавили к ним именованые параметры. Мы обсудим их через пару минут, а сейчас займемся параметрами по умолчанию.

Предположим, что у нас есть такой класс:

   1:  public class TestClass
   2:  {
   3:      public void PerformOperation(string val1, int val2, double val3)
   4:      {
   5:          Console.WriteLine("{0},{1},{2}", val1, val2, val3);
   6:      }
   7:  }

Теперь мы можем инстанциировать его и вызвать метод:

   1:  var testClass = new TestClass();
   2:  testClass.PerformOperation("val", 10, 12.2);

Но, что, если мы знаем "хорошие" значения параметров, которые используются чаще всего? До сего дня решением являлась перегрузка методов:

   1:  public class TestClass
   2:  {
   3:      public void PerformOperation()
   4:      {
   5:          PerformOperation("val", 10, 12.2);
   6:      }
   7:      
   8:      public void PerformOperation(string val1)
   9:      {
  10:          PerformOperation(val1, 10, 12.2);
  11:      }
  12:   
  13:      public void PerformOperation(string val1, int val2)
  14:      {
  15:          PerformOperation(val1, val2, 12.2);
  16:      }
  17:   
  18:      public void PerformOperation(string val1, int val2, double val3)
  19:      {
  20:          Console.WriteLine("{0},{1},{2}", val1, val2, val3);
  21:      }
  22:  }

Довольно длинно. Но C# 4.0 дает нам лучшее решение:

   1:  public class TestClass
   2:  {
   3:      public void PerformOperation(string val1 = "val", int val2 = 10, double val3 = 12.2)
   4:      {
   5:          Console.WriteLine("{0},{1},{2}", val1, val2, val3);
   6:      }
   7:  }

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

   1:  var testClass = new TestClass();
   2:  testClass.PerformOperation("val", 10);

Очень хорошо. Третий параметр в этом вызове приравнен к 12.2 по умолчанию. Теперь VB.NET разработчики перестанут смеятся над нами. Более того, параметры по умолчанию распространяются и на конструкторы:

   1:  public class TestClass
   2:  {
   3:      public TestClass(string someValue = "testValue")
   4:      {
   5:      }
   6:   
   7:      public void PerformOperation(string val1 = "val", int val2 = 10, double val3 = 12.2)
   8:      {
   9:          Console.WriteLine("{0},{1},{2}", val1, val2, val3);
  10:      }
  11:  }

Больше никаких многократных перегрузок конструкторов!

А что случится, если мы опустим значение val2 в вызове метода, показаном выше? Тоесть мы хотим указать val1 и val3, но оставить значение по умолчанию для val2. Мы не можем сделать это так:

   1:  var testClass = new TestClass();
   2:  testClass.PerformOperation("val", 10.2);

Этот код не скомпилируется, так как 10.2 не может быть приведено к int - здесь C# пытается оставить по умолчанию третий параметр, а не второй, как нам нужно. Итак, какой выход у нас есть? Мы можем использовать именованые параметры. Они состоят из указания имени параметра, двоеточия и значения, которое мы передаем. Тоесть вызов будет выглядеть так:

   1:  var testClass = new TestClass();
   2:  testClass.PerformOperation("val", val3: 10.2);

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

Вот вам еще одна интересная новая возможность C# 4.0 и еще один повод приглядываться к новой VS2010.

Перевод статьи: C# 4.0 New Features Part 2 - default and named parameters

2 комментария:

ulu комментирует...

Интересно, что в C# появятся возможности VB.Net (позднее связывание и необязательные параметры), которые сторонники C# традиционно считали "ненужными" и даже "вредными". Во всяком случае, пока не появился Ruby, и выяснилось, что динамические возможности -- это "круто".

VB.Net, в свою очередь, будет тоже догонять C# по фичам. Обещают примерное равенство. Интересно, сделают ли декларативное объявление обработчиков событий? Будет ли что-то наподобие RaiseEvent?

Анонимный комментирует...

разработка проекта разработка сайтов http://web-miheeff.ru разработка проекта