Why doesn't C# have VB.NET's 'with' operator?

Published 11 March 04 02:02 AM

Many people, including the C# language designers, believe that 'with' often harms readability, and is more of a curse than a blessing. It is clearer to declare a local variable with a meaningful name, and use that variable to perform multiple operations on a single object, than it is to have a block with a sort of implicit context.

For more information, see the Ask a C# Language Designer page.

[Author: Jon Skeet]

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Ferris Beuller said on March 11, 2004 2:45 AM:
We will have namespace aliases which I think is BAD, that coupled with lambda functions. C# is becoming Turd# whats next, partial methods? Dont even go there.
# Christoffer Skjoldborg said on March 11, 2004 6:21 AM:
Not having with in C# is about the only thing that I miss from VB. If you think with caues that much confusion then what about using? Shouldn't we really be spelling out the enitire namespace evertytime we use a type?
Of course with can be abused(like everything else) but if used right then it is a quite nice construct to save repetitive typing IMHO.




# Jon Skeet said on March 11, 2004 6:56 AM:
If you really miss it, you can create a local variable with a single character name. At that stage you only have to type one more character per line - is that really a hardship?
# Dave Donaldson said on March 11, 2004 7:17 AM:
I'm with Christoffer: when I program C#, I want the With statement. When scoped properly, I find it very handy. Of course, it can be abused, such as when you have nested With statements. That being said, if each language had the same features, would we need different languages?
# Julie Lerman said on March 11, 2004 7:40 AM:
local variable with single character name? If the argument is for readability, this doesn't seem to fit
# JW said on March 11, 2004 8:36 AM:
Jon,

Doesn't creating a short variable name cause code readability problems and isn't that the problem the C# team is trying to avoid with not including the With statement?

Personally, I find code that uses the With statement very readable.
# Jon Skeet said on March 11, 2004 11:03 AM:
Yes, it does. However, if someone *wants* with and the lack of readability it gives, presumably that isn't an issue for them. My point is that the lack of this "feature" really can't hurt *very* much for those who want it.
# Dejan said on March 11, 2004 11:16 AM:
If I had to single out one thing I miss in C# (I'm coming from Delphi) - it would surely be the lack of 'with' statement.

Mind you, having support for multiple structures in 'with' statement, like 'with A,B do' is abomination.
# Yuriy said on March 11, 2004 2:22 PM:
Delphi (i.e. Pascal) with statement has one very bad side effect. It is possible to alter meaning of a unit by adding a field to a structure in another unit. New fied can overlap local variables. This is not easy to track, because source control says that file was not changed recently.
# Aaron Lewis said on March 24, 2004 12:00 PM:
Being a paying customer and not, admittedly, a purist who thinks he knows how everyone else should code, I'd like to see the With operator in a future release of C#.

Just don't force the people who fuss over whether a black sweater goes better with their khakis than a dark blue one to use it, whatever you do!
# Marc Mueller said on April 14, 2004 9:53 AM:
The closest C# equivalent to VB's With statement is illustrated in the following example:

using (DataGrid x = DataGridList)
{
x.GridLines = GridLines.Both;
x.BackColor = System.Drawing.Color.White;
x.BorderStyle = BorderStyle.None;
x.ShowFooter = false;
x.ShowHeader = true;
x.AllowPaging = true;
x.AllowCustomPaging = true;
x.AllowSorting = true;
x.CellPadding = 4;
}
# Richard Back said on May 18, 2004 8:51 AM:
Jon, it'd be better for the debate if you stopped saying that 'with' gives a lack of readability. Clearly people's opinions vary on this one.
# Joe Robison said on May 25, 2004 4:15 PM:
However Using(x) only works if x implements the IDispose interface.

From a language "flavor" point of view (which is admittedly very subjective) it sort of feels right to me that VB, which tries to make your life easier at the expense of absolute purity of the language (see RaiseEvent for an example), would support With while C# does not. It's a bit odd that the result is that in this case VB code can be more terse than C#. I actually find it stranger that C# has the using() statement, which seems to be more in keeping with VB's philosophy.
# Brian Clifton said on June 2, 2004 11:37 PM:
WITH is horrible. It's only a problem for people that haven't programmed in a real language before; VB would be better off for those people anyhow. Think about it VB lovers, WITH "saves so much space", but you also use THEN and END IF as opposed to { and }. THEN and END IF appear MUCH more often than WITH ever should. If you rely on mechanisms like WITH, then you should seriously reconsider how you design your software, if you do at all. If I had to complain about C# lacking features, I would be asking where C-style Unions are. Splitting packets manually rather than by a union of an array and a struct is a pain
# invid said on June 11, 2004 11:00 AM:
Uh... respect?
As you can see here, there are quite a few people who like 'with', and Mr Clifton, you just disrespected ALL of them - so anyone who likes 'with' is a terrible programmer, and anyone who programs in VB is not a 'real' programmer? This sounds like a post that belongs on a Linux board (in keeping with Mr Clifton's blanket statements)
# Jeff Brown said on July 5, 2004 3:20 AM:
I must agree with 'invid': Mr. Clifton is coming across a little on the arrogant side. I can see both sides of this issue, and I think we should appreciate the subjectiveness of it, without resorting to degrading the validity of others' programming ability.
# Anon said on July 22, 2004 11:18 AM:
With is a code smell, learn better way's to program, for example... Rather than working with built in types... inherit from them so you can improve the API, consider the following previous example

using (DataGrid x = DataGridList)
{
x.GridLines = GridLines.Both;
x.BackColor = System.Drawing.Color.White;
x.BorderStyle = BorderStyle.None;
x.ShowFooter = false;
x.ShowHeader = true;
x.AllowPaging = true;
x.AllowCustomPaging = true;
x.AllowSorting = true;
x.CellPadding = 4;
}

rather than doing that... consider an argument accumulator pattern which allows named arguments in any order with all being optional.

aDataGridList
.GridLines(GridLines.Both)
.BackColor(System.Drawing.Color.White)
.CellPadding(4);

aDataGridList
.AllowPaging(true)
.AllowCustomPaging(true)
.AllowSorting(true)
.CellPadding(4);

aDataGridList
.GridLines(GridLines.Both)
.BackColor(System.Drawing.Color.White)
.BorderStyle(BorderStyle.None)
.ShowFooter(false)
.ShowHeader(true)
.AllowPaging(true)
.AllowCustomPaging(true)
.AllowSorting(true)
.CellPadding(4);

Basically, whenever you find yourself needing to call the same object a bunch of times in a row... consider extending that object and providing either a single method to do that, or expose all props in an accumulator, either way... code that calls an object over and over and over... belongs in that object in the first place. No object should require you to set a bunch of properties constantly, that's why we have inheritance.
# Anon said on July 23, 2004 10:36 AM:
It shouldn't be too difficult to create a code generator that uses reflections to automatically generate an accumulator wrapper for any class... every property that reflections finds simply generates a method like so...

class DataGridWrapper:DataGrid{
public DataGridWrapper SetShowFooter(bool showFooter){
ShowFooter=showFooter;
return this;
}
}

accumulators drastically improve the API of any object and are easily machine generated.
# Anon said on July 23, 2004 3:08 PM:
Here's a class to generate an accumulator decorator for any type... use like

Response.Write(new ArgWrapperGenerator(typeof(DataGrid)).Generate()); //writes an argument acumulator decorator class for the datagrid..

now you can do this...
new DataGridAccumulator(aGrid)
.SetThis(bla)
.SetThat(bla)
.SetSomethingElse(bla);

no with statement necessary....

code below..
--------------------------------

using System;
using System.Reflection;
using System.Collections;

namespace AccumulatorDecorator {
public class ArgWrapperGenerator {
Type theGeneratedFor;

public ArgWrapperGenerator(Type generateFor) {
theGeneratedFor=generateFor;
}
public string Generate() {
string result="";

Hashtable nameSpaces = new Hashtable();
foreach(PropertyInfo aProp in theGeneratedFor.GetProperties())
if(aProp.CanWrite)
nameSpaces[aProp.PropertyType.Namespace]=aProp.PropertyType.Namespace;

foreach(DictionaryEntry aNamespace in nameSpaces)
result+="using "+aNamespace.Value+";\n";

result+="public class "+theGeneratedFor.Name+"Accumulator{\n";
result+="\t\t"+theGeneratedFor.Name+" the"+theGeneratedFor.Name+";\n\n";
result+="\t\tpublic "+theGeneratedFor.Name+"Accumulator("+theGeneratedFor.Name+" a"+theGeneratedFor.Name+"){\n";
result+="\t\t\tthe"+theGeneratedFor.Name+"=a"+theGeneratedFor.Name+";\n";
result+="\t\t}\n";

foreach(PropertyInfo aProp in theGeneratedFor.GetProperties())
if(aProp.CanWrite)
result+=GetProp(aProp);

result+="\t}\n";

return result;
}
string GetProp(PropertyInfo aProp){
string result="\t\tpublic "+theGeneratedFor.Name+"Accumulator Set"+aProp.Name+"("+aProp.PropertyType.Name+" a"+aProp.Name+"){\n";
result+="\t\t\tthe"+theGeneratedFor.Name+"."+aProp.Name+"=a"+aProp.Name+";\n";
result+="\t\t\treturn this;\n";
return result+"\t\t}\n";
}
}
}
# Anon-E-Moose said on October 22, 2009 9:57 PM:

Personally, I never used the with statement much in my vb days. But it had it's uses. Now that I'm using C#, and have to type Properties.Settings.Default.[variable] every time I want to access a property, the with statement would come in extremely handy, as Properties.Settings.Default doesn't implement IDisposable, and creating a variable to hold Properties.Settings.Default is still pretty much pointless, because in my case, I'm using this property very much like a local variable, where I don't want to type Properties.Settings.Default every time I need to access it, because I need to do this a lot, and thus this will take a lot of added time, that doesn't need to be taken.

# Jano said on November 19, 2009 4:45 AM:

I find with statement in VB.NET extremely annoying (apart from subjective readability issue where I reckon it is reducing the readability) when debugging in VS 2005.

It is very slow and manual process to 'Add Watch' where inside a "with" block - or expecting a tool tip to pop up showing the current value of a variable but doesn't work in VS2005.

Although I am a C# person I have to use VB.NET frequently, and this is one of those things that bugs me all the time.

# Krishan Ariyawansa said on November 22, 2009 9:02 PM:

It is possible with C#. Compiler will not reject the following code block.

               Table table = new Table

               {

                   CellPadding = 0,

                   CellSpacing = 0,

                   BorderWidth = 0,

               };

Cheers, Happy code-ing.

# Wardy said on December 14, 2009 7:51 AM:

LOLZ ...

All this over the word "WITH" haha ...

I started out on VB then moved to .NET, I have to admit I see VB as a "training language" most people I know even those that work with it tell me this causes a lot of confusion about how to professionally use VB.

My advice, learn your language and learn it well, don't complaing about it.

I came a across a similar issue with optional parameters the other day, had to use reflection instead.

Bit of a ball ache but it was my choice to live in fluffy C# land ...

Just out of curiosity ... what MSIL does this With keyword generate ?

Technically I reckon it makes a mess of your pre jit code so why not steer clear of it :)

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

This Blog

Syndication

Page view tracker