English 中文(简体)
C#语法糖-设置对象属性的新方法?
原标题:C# syntax sugar - new way to set object attributes?

对于这里的铁杆C#程序员来说,这似乎是一个完全愚蠢的问题——然而,我刚刚在AWS SDK论坛上看到了一段示例代码,并完全被它所左右:

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

这让人想起了旧的VB6<code>With。。。End With语法,这是我长期以来一直为C#中缺乏的语法而哀叹的——我在VS2008项目中编译了它,它起到了很好的作用,保存了许多单独引用这些属性的行。

我确信我以前读过一些文章,解释为什么C#中没有VB6风格的With-块,所以我的问题是:这种语法在语言中一直存在吗,还是最近.NET的更改启用了它?我们能在同一个糖中覆盖所有对象实例化和属性更改吗?

最佳回答

他们实现了所有这些方法,每个方法还将返回RunInstancesRequest对象(也称为this)。它被称为Fluent接口

问题回答

这不是更好吗?

RunInstancesRequest runInstance = new RunInstancesRequest 
{
    MinCount = 1, 
    MaxCount = 1, 
    ImageId = GetXMLEleemnt("ami"), 
    InstanceType = "t1.micro"
};

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

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");

我不知道这是被认为是句法上的糖,还是纯粹的格式。

我认为这种技巧不同于With。。。VB中的语法。我认为这是一个链接的例子。每个方法都返回其自身的一个实例,这样您就可以链接方法调用。

请参阅C中的方法链接#

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

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

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

将它与VB6进行比较是不公平的。。。End With语法,因为在这种情况下发生的事情要清楚得多(关于VB6的With…End With[/code>,我要说的唯一好处是它至少没有Javascript那么糟糕,因为它需要前面的点)。

正如人们所说,这是“流畅的界面”和<code>这一事实的结合运算符允许在其前后有空格,因此我们可以将每个项放在换行符上。

<code>StringBuilder</code>是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#具有属性。这使得分配不同属性的最惯用方法是对相关setter进行调用,该调用在语法上与设置字段相同。然而,它确实阻碍了流畅界面习惯用法的大部分最常见使用。

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

这种语法一直存在





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...