Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

As C# has progressed, many language features have been added. It has come to the point where it's becoming unreadable for me.

As an example, consider the following code snip from Caliburn.Micro code here:

            container = CompositionHost.Initialize(
                   new AggregateCatalog(
                      AssemblySource.Instance.
                             Select(x => new AssemblyCatalog(x))
                               .OfType<ComposablePartCatalog>()
                )
            );

Now, this is just a small example.

I have a number of questions:

  • Is this a common or known problem?
  • Is the C# community finding the same?
  • Is this an issue with the language, or is it the style used by the developer?

Are there any simple solutions to better understand others code and avoid writing code in this way?

share|improve this question
6  
Its the lambda function, they are hard to read until you really get them. –  Ryathal Jun 4 '12 at 12:58
8  
I think you really didn't know the syntax as well as you thought. With practice reading your example is simple. –  ChaosPandion Jun 4 '12 at 13:00
6  
@Thomas Owens: Holy shit man, at least give us some time to edit questions to keep them open. 15 minutes? Come on now. –  Steve Evers Jun 4 '12 at 13:06
4  
@DannyVarod: 1. "No" is not an acceptable answer 2. The question is closed 3. If you agree that the question shouldn't be here then flag/vote to close it or edit it to be better. –  Steve Evers Jun 4 '12 at 13:11
1  
@Avi downvotes tell that people think there is something wrong with your question - learn from it –  user1249 Jun 5 '12 at 8:52

6 Answers 6

up vote 6 down vote accepted

Quick note on where the language is should clear it up: C# is a general purpose programming language; unlike C (like C++) it strives for high abstraction; unlike Lisp dialects it aims for practical expressiveness, and, unlike Java, it is more aggressively driven - Microsoft is quick to respond to demand.

That is why it's turning into a mixture of LINQ, lambdas and weird new keywords - it's adapting to new problem domains quickly, and this is indeed a slippery slope towards a language so complex that very few can use it correctly (like C++). It's not a problem with C# itself, it's a problem with any language with these ambitious goals.

The community is aware of this and, more importantly, the guys behind C# are acutely aware of this (the few blog entries and podcasts on what was behind the new additions in C# 5.0 show how bad these guys want to keep things simple). Microsoft is trying to take some of the load off their flagship such that it doesn't become a tarpit: the introduction of the DLR, a bright spotlight over new languages (F#).

Moreover, course material on C# (including MS certifications) recommends different (but consistent) styles of use for C# depending on the problem - choose your weapon and stick to it: Fluent-style LINQ on some problems, lambdas with TPL on others, plain-old for most.

share|improve this answer
2  
Can you explain what you mean with "unlike Lisp dialects it aims for practical expressiveness"? –  Giorgio Jun 20 '13 at 16:25

No. C# is giving us more options to write code more succinctly. This can be used or abused. If used properly, it makes the code easier to read. If used improperly it can make the code harder to read. But bad programmers have always had a skill in writing hard to read code.

Lets take two examples, both based on examples found on StackOverflow regarding the same problem, finding types with a specific attribute:

C# 2.0:

static IEnumerable<Type> GetTypesWithAttribute<TAttribute>(bool inherit) 
                              where TAttribute: System.Attribute
{
    foreach(Assembly assembly in AppDomain.Current.GetAssemblies())
    {
        foreach(Type type in assembly.GetTypes()) 
        {
            if (type.IsDefined(typeof(TAttribute),inherit))
                yield return type;
        }
    }
}

C# 4.0:

IEnumerable<Type> GetTypesWith<TAttribute>(bool inherit) 
                              where TAttribute: System.Attribute
{ 
    return from assembly in AppDomain.CurrentDomain.GetAssemblies()
           from type in assembly.GetTypes()
           where type.IsDefined(typeof(TAttribute),inherit)
           select type;
}

IMHO, the new syntax makes it a lot easier to read.

share|improve this answer
    
the new syntax is indeed easier to read, but easier to comprehend, as in what is going on under the hood? The first example is understandable, the second is more readable. –  nawfal Nov 22 '12 at 22:23
3  
@nawfal In my experience, people have much more trouble understanding "yield return" constructs than linq statements; so I would argue the second is more readable and understandable. Neither really tells you what is going on under the hood, since both map to abstractions far from how processors actually work. –  Chuu Mar 12 '13 at 21:10

When LINQ was added, it popularized a style of coding involving lots of Fluent-style method chaining, and passing of lambdas as parameters.

This style is very powerful once you're comfortable with it. However it can be abused to make fairly unreadable code. I don't think your example is too bad, although the indentation is kind of random (and that's a common feature of this style of code, Visual Studio doesn't auto-indent it very consistently).

At my workplace, we discussed this coding style when reviewing our coding standards earlier this year, and we decided to encourage developers to break up code like that: specifically, not to create and initialize anonymous objects inside a function call. So your code would become:

var assemblyCatalog = AssemblySource.Instance
    .Select(x => new AssemblyCatalog(x))
    .OfType<ComposablePartCatalog>();
var aggregateCatalog = new AggregateCatalog(assemblyCatalog);
container = CompositionHost.Initialize(aggregateCatalog);
share|improve this answer
1  
Isn't it kind of strange to create a new type, and then dynamically switch on that type right afterwards? –  DeadMG Jun 5 '12 at 6:30
    
Probably, I just chopped up the code snippet without any real consideration of what its intention was. Just wanted to split all of the instantiations off into their own lines of code to show what effect that would have on the look of the code. –  Carson63000 Jun 6 '12 at 5:37
    
I take the blame for the indentation :(). Here's the original: devlicio.us/blogs/rob_eisenberg/archive/2010/07/08/… –  user18254 Jun 6 '12 at 10:05
1  
I fully agree with that answer. The problem in the example piece of code is not the new C# syntax, its that the writer tried to be clever with a "one-liner" code. There is this old rule dating back from UNIX : everything should only do one thing, and do it well. It apply to class, it apply to method and, of course, it most certainly apply to lines of code. –  Laurent Bourgault-Roy Dec 14 '12 at 23:22

The code in your example is not easily readable because

  • It mixes many notions (Composition, Catalogues, Aggregates, Assemblies, ComposableParts...) with several levels of nesting while the calling code should typically have to deal with only one level. Looks a bit like a violation of the Law of Demeter only with nested method calls instead of a chain of sub-sub-properties. This muddles the intention behind the line of code somewhat.

  • There's a weird singleton usage - AssemblySource.Instance.Select() implies that Instance is an IEnumerable, which is a bit awkward.

  • The x variable in the lambda expression is ugly. Generally you try to give your lambda variables intention revealing names - helps the reader identify what kind of data the function is about, even if he's not familiar with lambdas.

  • It's not clear why you should filter with OfType<T>() a collection of objects you've just newed up...

However, all these flaws relate to the way the original developer wrote the code and how expressive he designed it to be. This is not something specific to the latest versions of C# and the appearance of lambda expressions.

More generally, it helps if the reader of your code knows how lambdas work, but with clear enough naming you almost always manage to make your code readable even to someone with a pre-.NET 3.5 background.

share|improve this answer

Anytime a new version of popular language gains new constructs, similar debates arise.

I also had these doubts years ago (http://gsscoder.blogspot.it/2009/08/use-csharps-features-wisely.html).

In my opinion C# is evolving in an elegant and consistent way.

Code in your sample is not complex, maybe you're not used with lamda expressions.

The problem is that C# is not only an object oriented language, it now supports also functional constructs (http://archive.msdn.microsoft.com/FunctionalCSharp/).

share|improve this answer

It took me a little while to understand Lambda syntax, and I'm from a mathematics and physcis background. It's a bit similar to mathematical expressions, althose they use -> instead of =>:

Maths example f(x) := x->x+2 this reads as "Function f of x is defined as x maps on to x+2

c# example del myDelegate = x => x +2; this reads as "myDelegate is a function such that myDelegate (x) maps x on to x+2

The inconsistency between maths and programming doesn't really help, although I suppose -> had already been taken up in C++ as "property of" (urrgghh!)

http://en.wikipedia.org/wiki/List_of_mathematical_symbols

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.