CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Greg Young [MVP]


Syntactical Molasses

There are some things about C#'s syntax that really get to me. Here is one of them.. I just hate the way it reads and makes the intention of the code so much more difficult to understand.

 

[Test, ExpectedException(typeof(ArgumentNullException))]
public void GetAllFilesMatching_With_NullPath_ThrowsArgumentNullException()
{
    foreach (string s in DirectoryWalker.GetAllFilesMatching(null, AlwaysTruePredicate)) { }
}

 

 

Yuck... Whats your favorite Syntactical Molasses in C#?



Comments

Peter Ritchie said:

In case anyone is wondering, why does Greg need the foreach if he just wants to see if GetAllFilesMatching throws an exception with a null argument?
# January 17, 2008 3:52 PM

Greg said:

yeah I guess its not obvious ... here is the method signature being tested ... it will make alot more sense.

public IEnumerable<string> GetAllFilesMatching(string Path, Predicate<string> Predicate)

# January 17, 2008 4:35 PM

Chris Mullins said:

I gotta go with Peter - I don't get why the ForEach is there. Even given the iterator signature of the method you're calling, I think it's just obscuring the purpose of the test. Just Call: GetAllFilesMatching(null, AlwaysTruePredicate)
# January 17, 2008 4:46 PM

Chris Mullins said:

One of the annoying syntax thing for me in C# is the class / ctor syntax.

Public class MyClass

{

  public MyClass(){}

}

Why do I need to type "MyClass" twice? (or 3 times, or 10 times).

(Prior to C# 3, the most annoying syntax for me was Property Accessors. Talk about excessive typing for no good reason!)

# January 17, 2008 4:50 PM

Greg said:

Chris you can't "just call" it ... the method doesn't get called until the enumerator gets called ...

with just this...

DirectoryWalker.GetAllFilesMatching(null, AlwaysTruePredicate)

The test fails as it never gets called :-)

 

I could do something like IEnumerable<string> s = ... then call MoveNext() but thats quite weird too ... 

# January 17, 2008 4:57 PM

Peter Ritchie said:

With regard to Greg's blog post code, and *why* he needs the foreach (or more specifically, a call to IEnumerator.MoveNext) see: http://blogs.msdn.com/ericlippert/archive/2007/09/05/psychic-debugging-part-one.aspx http://blogs.msdn.com/ericlippert/archive/2007/09/05/psychic-debugging-part-two.aspx
# January 17, 2008 5:07 PM

JD Conley said:

Molasses eh... Let's see. I dislike inline anonymous delegates in method calls. Seeing "})" just looks strange.

I also dislike full syntax for lambdas (no type inference).

I absolutely hate that  {} is required for single line try/catch.

And, finally, why the heck do I have to break out of the last block in a switch.

# January 17, 2008 5:24 PM

Jimmy Bogard said:

On another note, don't you have issues with refactoring with your test naming convention? I used to dread renaming methods or properties, as I would have to manually fix all of the test names pertaining to that test.
# January 17, 2008 6:12 PM

Dave Foley said:

How about:

TypeOfEnum enumValue = (TypeOfEnum) Enum.Parse(typeof(TypeOfEnum), someValue);

and I really want hashtables to be prettier:

Dictionary<string, string> d = new Dictionary<string, string>();javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$ctl00$ctl00$bcr$bcr$bcr$ctl14$ctl02$ctl02$ctl02$btnSubmit", "", true, "CreateCommentForm", "", false, true))

Add

d.Add("blah", blah");

d.Add("blah2", blah2");

CallSomeMethod(d);

... as opposed to something more boo-like:

CallSomeMethod({"blah": "blah", "blah2" : "blah2"});

# January 17, 2008 7:17 PM

Lothan said:

My favorite is the null != DBNull.Value fiasco that increases the complexity of working with data access logic. Because of this blunder, simple code like this decimal cost = (decimal) reader["Cost"] ?? 0; actually reads like a Daily WTF submission decimal cost = (decimal) (reader["Cost"] != DBNull.Value ? reader["Cost"] : 0);
# January 17, 2008 11:28 PM

FransBouma said:

I find the required 'break;' after a case clause the most stupid thing I've ever seen in a language. It's completely redundant: there's no fall-through, so there's never going to be a case clause which flows through into the next one. Still a break is required. If you don't specify a break, the compiler whines that there's no fall through (duh!) and a break is required, but ... that's not necessary, there's no fall through, csc!
# January 18, 2008 3:40 AM

FOR said:

I see 'syntactical molasses' every day, but it's not the language's fault. No matter what they tell you, it's a people problem, right ?

Sure, some languages are more verbose than others (in my personal experience, Java was the most verbose I ever encountered), but it's up to the developers to make good or bad use of the language. No ?

# January 18, 2008 8:00 AM

Peter Ritchie said:

Indeed, WRT "break".  If the language will give me an error that the break is missing, it knows exactly where it should be; so I don't need it.  It's not like C++ where you can fall through to the next case...

Similar to "Error: missilng semicolon".  Well, then put the damn semicolon in then!

# January 18, 2008 9:36 AM

Joe Chung said:

Better? var files = DirectoryWalker.GetAllFilesMatching(null, s => true);
# January 18, 2008 7:32 PM

Chad Myers said:

Generics can get pretty sticky when you have anything that might be nested. Like if you find yourself in this situation:

Dictionary<string, IList<IItem>> itemDict = new Dictionary<string,IList<IItem>>();

# January 19, 2008 2:15 AM

matt said:

That's nothing to do with C#. It's just poor API design in the test framework (use of attributes, not objects or functions) and poor test code (the foreach is *how* the tested behaviour is triggered, but does not communicate why). How about: AssertThrows(typeof(ArgumentNullException), delegate { IterationOver(DirectoryWalker.GetAllFilesMatching(null, AlwaysTruePredicate)); }); Or with a bit of refactoring: AssertThat(delegate{ IterationOver(DirectoryWalker.GetAllFilesMatching(null, AlwaysTruePredicate))}, ThrowsException(typeof(ArgumentNullException)));
# January 21, 2008 4:04 AM

Greg said:

matt:

You say the foreach should be an iterate method ... is it any clearer with

IterationOver(DirectoryWalker.GetAllFilesMatching(null, AlwaysTruePredicate))

WHY I am iterating over something that should fail in a precondition?

if this is a List<T> returned as an IEnumerable it throws an exception up front when I call the GetAllFilesMatching method and iterateover is never called.

# January 21, 2008 2:42 PM

Scott said:

My favorite was the "toArray" method of ArrayList.

www.lazycoder.com/.../arraylisttoarray

"That’s ok, but now you have an ArrayList, not an array of type “Group”. Luckily you can use the ToArray() method of the ArrayList class to convert it to a Group array. There is a catch though. Even though you pass in a type (”Group”) it returns an array of objects. You need to explicitly cast it as the type you want the array to be of.

arGroups = (Group[]) listGroups.ToArray(typeof(Group));

"

Generics killed this little bit of heaven.

# January 22, 2008 1:37 PM

JohnOpincar said:

I found myself doing this one day:

List<ITrans> list = new List<ITrans>();

double sum = 0;

list.ForEach(delegate(ITran t) { sum += t.Amount; });

Then slapped myself and changed it to use a real for loop.

# February 15, 2008 6:32 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!