6

对于这里的铁杆 C# 编码人员来说,这似乎是一个完全愚蠢的问题 - 然而,我刚刚在 AWS SDK 论坛中看到了一段示例代码,并完全被它扫视了:

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

这很容易让人想起旧的 VB6With ... End With语法,我一直为 C# 中没有这种语法感到遗憾——我已经在我的 VS2008 项目中编译了它,它可以很好地工作,节省了许多单独引用这些属性的单独行。

我确定我过去读过文章,解释为什么 VB6 样式With块不在 C# 中,所以我的问题是:这种语法是否一直存在于语言中,或者它是最近的 .NET 更改启用了吗?我们可以在相同的糖中覆盖所有对象实例化,然后是属性更改吗?

4

10 回答 10

26

这不是更好吗?

RunInstancesRequest runInstance = new RunInstancesRequest 
{
    MinCount = 1, 
    MaxCount = 1, 
    ImageId = GetXMLEleemnt("ami"), 
    InstanceType = "t1.micro"
};
于 2010-10-15T14:16:58.943 回答
16

他们实现了所有这些方法,每个方法也将返回RunInstancesRequest对象(又名,this)。它被称为流畅的界面

于 2010-10-15T14:16:54.720 回答
4

它不是语法糖。这些方法只是设置一个属性并返回this对象。

于 2010-10-15T14:15:14.530 回答
4
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");

我不知道这是否被认为是语法糖,或者只是纯粹的格式。

于 2010-10-15T14:57:12.700 回答
3

我认为这种技术与 VB 中的 With... 语法不同。我认为这是链接的一个例子。每个方法都返回一个自身的实例,因此您可以链接方法调用。

请参阅C# 中的方法链

于 2010-10-15T14:17:55.900 回答
1

此语法适用的原因RunInstancesRequest是您进行的每个方法调用都返回原始实例。出于同样的原因,同样的概念可以应用于 StringBuilder,但并不是所有的类都有以这种方式实现的方法。

于 2010-10-15T14:17:00.003 回答
1

我更喜欢有一个构造函数,它将所有这些属性值作为参数并将它们设置在类中。

于 2010-10-15T14:19:12.170 回答
1

它一直存在于 C# 中,实际上也存在于任何 C 风格的 oo 语言中(嗯,除了 C 本身之外,最流行的 C 风格的语言!)

将它与 VB6With...End With语法进行比较是不公平的,因为在这种情况下发生的事情要清楚得多(关于 VB6,我要说的唯一一件好事With...End With是至少它不像 Javascripts 那样糟糕,因为它需要之前的点) .

正如人们所说,结合了“流畅的界面”和.运算符允许前后空格的事实,因此我们可以将每个项目放在换行符上。

StringBuilder是 C# 中最常见的情况,如:

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

一个相关但不完全相同的模式是链接不可变对象的方法,该对象返回与以下相同类型的不同对象:

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

还有一个是从 LINQ 相关方法返回修改后的对象IEnumerable<T>IQueryable<T>

尽管它们在返回不同的对象方面有所不同,而不是修改可变对象并返回相同的对象。

它在 C++ 和 Java 中比在 C# 中更常见的主要原因之一是 C# 具有属性。这使得分配不同属性的最惯用方法是调用相关的 setter,这在语法上与设置字段相同。然而,它确实阻止了流畅界面习惯用法的大部分最常见用法。

就个人而言,由于不能保证流畅的界面习语(没有什么可说的MyClass.setProp(32)应该返回this,或者实际上,它不应该返回32,这在某些情况下也很有用),并且由于它在 C# 中不是惯用的,我宁愿避免除了 with StringBuilder,这是一个众所周知的例子,它几乎作为一个单独的StringBuilder习语存在于 C# 中

于 2010-10-15T16:59:47.097 回答
0

这种语法一直存在

于 2010-10-15T14:15:25.250 回答
-2

请参考扩展方法(C#编程指南)

于 2010-10-15T19:31:59.480 回答