Why is the with() construct not included in C#, wh

2019-04-21 15:36发布

问题:

I am C# developer. I really love the curly brace because I came from C, C++ and Java background. However, I also like the other programming languages of the .NET Family such as VB.NET. Switching back and forth between C# and VB.NET is not really that big of deal if you have been programming for a while in .NET. That is very common approach in the company where I work. As C# guy, I really like the XML literal and with keywords provided by the VB.NET compiler. I wish Microsoft had included those features in C# also.

I am just curious , what other developer has to say about it!

回答1:

I wouldn't be suprised if "With" or a similar feature is added to C# eventually along with other heretofore popular exclusively VB features. There was a lot of talk in the C# 4.0 preview presentations recently at PDC and elsewhere of the increased "focus on language parity" starting with C# 4.0 and VB 10.



回答2:

Personally I don't like WITH when it's used after construction - if you need to do several things with an object after it's initialized, usually that behaviour should be encapsulated in the type itself. If you really want to do something like WITH, it's only a matter of declaring a short variable and optionally introducing a new scope.

However, it is useful to be able to compactly initialize an object with several properties - which is precisely why C# 3 allows you to write:

MyObject x = new MyObject { Name="Fred", Age=20, Salary=15000 };

There are limitations to this (which the optional and named parameters in C# 4 will help to overcome) but it's better than it was without leading to potential messes/ambiguities.

(On the XML literal front, I'm again with the C# team - XML is a very specific technology to put into a language. If they could come up with a generalised form which happened to create XML but could be used to create other trees too, that would be nice - just as query expressions aren't directly tied to IEnumerable or IQueryable.)



回答3:

You can replace VB.Net's With by creating a quick single-letter variable name. It's actually less code, since With also requires an End With later on.

For example, one thing I used to need to do fairly often was iterate over the rows in a datatable for a control/break style report.

In vb.net, that might look like this:

Dim CurCustomerName As String 
Dim CustomerSalesTotal As Decimal

Dim ds As DataSet = GetReportData()
With ds.Tables(0).Rows
   Dim i As Integer = 0
   While i < .Count
       ''//{
       CurCustomerName = .Item(i)("CustName")
       CustomerSalesTotal = 0
       PrintHeaderLine(CurCustomerName)

       While i < .Count AndAlso CurCustomerName = .Item(i)("CustName")
            ''//{
            PrintItemLine(.Item(i)("OrderTotal"))
            CustomerSalesTotal += .Item(i)("OrderTotal")

            i+= 1
       End While ''//}
       PrintSubTotalLine(CustomerSalesTotal)
   End While ''//}
End With

The C# would look like this:

string CurCustomerName;
Decimal CustomerSalesTotal;

DataSet ds = GetReportData();
DataRowCollection r = ds.Tables[0].Rows;
int i=0;
while (i<r.Count)
{
    CurCustomerName = r[i]["CustName"];
    CustomerSalesTotal = 0;
    PrintHeaderLine(CurCustomerName);

    while (i<r.Count && CurCustomerName == r[i]["CustName"])
    {
        PrintItemLine(r[i]["OrderTotal"]);
        CustomerSalesTotal += r[i]["OrderTotal"];

        i++;
    }
    PrintSubTotalLine(CustomerSalesTotal);
}

The thing to notice here is that the C# version actually needed less typing, because the VB couldn't combine WITH with the array index, and had to go through the .Item property for certain things. It's not a big deal here, but imagine if the report had 20 fields instead of 2 and had to break on 3 items instead of 1.

Of course, you could use the technique demonstrated in C# for VB as well. But the main thing to note is that WITH doesn't really give you much.



回答4:

It's about developer preferences, but I'm with you about WITH. My preference is to minimize the number of variables in play, and the scope within which they live. The philosophy of C# seems to be much the same. But in this case the responses here seem to suggest that adding (and making yourself responsible for) a variable is a Good Thing compared to a construct which, to me, is very similar to lambdas.



回答5:

I feel it is rather arbitrary to only allow 'mass' property setting during initialization. I really don't get why this would be 'bad':

MyObj myObj = ObjFactoryFunction();

...

if(someCondition)
  myObj { Prop1 = 1, Prop2 = 2 };

I feel that this example code is clean and concise.



回答6:

Usually when I see a request for a with feature in C#, I see code that would benefit from refactoring. Usually when the refactoring is done, the supposed need for with is gone.

I like the way my code works out when I build a fluent interface in to an object; it has some similarities to with. If I was designing MessageBox.Show(), I might write:

new MessageBox()
    .SetText("Hello World!")
    .SetButtons(MessageBox.Buttons.OK)
    .SetIcon(MessageBox.Icon.Information)
    .Show();

You can also see something similar with Linq:

var q = Enumerable.Range(1, 100)
            .Where(x => x % 2 == 0)
            .Select(x => x * x);

It feels a bit like with but seems to fit naturally in to the language I already have.