Синтаксис C # сахара - новый способ установить атрибуты объекта? - PullRequest
6 голосов
/ 15 октября 2010

Для хардкорных кодеров C # здесь это может показаться совершенно глупым вопросом - однако я только что натолкнулся на фрагмент примера кода на форуме AWS SDK и был совершенно потрясен им:

   RunInstancesRequest runInstance = new RunInstancesRequest()
    .WithMinCount(1)
    .WithMaxCount(1)
    .WithImageId(GetXMLElement("ami"))
    .WithInstanceType("t1.micro");

Это очень напоминает старый синтаксис VB6 With ... End With, который я долго оплакивал по поводу отсутствия в C # - я скомпилировал его в своем проекте VS2008, и он работает, сохраняя многочисленные отдельные строки, ссылающиеся на эти атрибуты по отдельности.

Я уверен, что читал статьи в прошлом, объясняющие, почему With -блок в стиле VB6 не был в C #, поэтому мой вопрос: существует ли этот синтаксис всегда на языке, или это недавнее изменение .NET, которое включило его?Можем ли мы покрыть все экземпляры объектов, за которыми следуют изменения атрибутов в одном и том же сахаре?

Ответы [ 10 ]

26 голосов
/ 15 октября 2010

Разве это не лучше?

RunInstancesRequest runInstance = new RunInstancesRequest 
{
    MinCount = 1, 
    MaxCount = 1, 
    ImageId = GetXMLEleemnt("ami"), 
    InstanceType = "t1.micro"
};
16 голосов
/ 15 октября 2010

Они реализовали все эти методы, каждый из которых также будет возвращать объект RunInstancesRequest (он же this). Это называется Свободный интерфейс

4 голосов
/ 15 октября 2010
RunInstancesRequest runInstance = new RunInstancesRequest()
.WithMinCount(1)
.WithMaxCount(1)
.WithImageId(GetXMLElement("ami"))
.WithInstanceType("t1.micro");

==

RunInstancesRequest runInstance = new RunInstancesRequest().WithMinCount(1).WithMaxCount(1).WithImageId(GetXMLElement("ami")).WithInstanceType("t1.micro");

Я не знаю, считается ли это синтаксическим сахаром или просто чистым форматированием.

4 голосов
/ 15 октября 2010

Это не синтаксический сахар. Эти методы просто устанавливают свойство и возвращают объект this.

3 голосов
/ 15 октября 2010

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

См. Цепочка методов в C #

1 голос
/ 15 октября 2010

Он всегда существовал в C # и действительно на любом языке C-style (да, самый популярный язык C-стиля, кроме самого C!)

Несправедливо сравнивать его с синтаксисом VB6 With...End With, так как в этом случае гораздо понятнее (о единственной хорошей вещи, которую я могу сказать о With...End With VB6, это, по крайней мере, не так плохо, как Javascripts, поскольку он требует предыдущих точек).

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

StringBuilder - наиболее часто встречающийся случай в C #, например:

new StringBuilder("This")
  .Append(' ')
  .Append("will")
  .Append(' ')
  .Append("work")
  .Append('.');

Связанный, но не совсем такой же шаблон - это то, где вы объединяете методы неизменяемого объекта, который возвращает другой объект того же типа, что и в:

DateTime yearAndADay = DateTime.UtcNow.AddYears(1).AddDays(1);

Еще один возвращает измененные объекты IEnumerable<T> и IQueryable<T> из методов, связанных с LINQ.

Они отличаются тем, что возвращают разные объекты, а не изменяют изменяемый объект и возвращают тот же объект.

Одна из основных причин того, что это чаще встречается в C ++ и Java, чем в C #, заключается в том, что C # имеет свойства. Это делает наиболее идиоматическим средством присвоения различных свойств вызов связанного установщика, который синтаксически совпадает с установкой поля. Тем не менее, он блокирует большую часть наиболее распространенного использования языка интерфейса.

Лично, поскольку идиома свободного интерфейса не гарантируется (нечего сказать, MyClass.setProp(32) должен возвращать this или действительно, что он не должен возвращать 32, что также было бы полезно в некоторых случаях), и так как в C # это не так идиоматично, я предпочитаю избегать этого, кроме StringBuilder, который является настолько известным примером, что он почти существует как отдельная StringBuilder идиома в C #

1 голос
/ 15 октября 2010

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

1 голос
/ 15 октября 2010

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

0 голосов
/ 15 октября 2010
0 голосов
/ 15 октября 2010

Этот синтаксис существовал всегда

...