
Hidden features of C# - yread
http://stackoverflow.com/questions/9033/hidden-features-of-c
======
jb55
One powerful feature I don't see being used very often is simulating
typeclasses via contraints on generic types:

    
    
        public static IEnumerable<CalculatedTax> CalculateTaxes<T>(this T t)
          where T : IOrderItems, IAddress {}
    

This adds an extension method to any type that implements those interfaces.
Using this technique I have been able to make my interfaces much smaller and
have generic functions which apply to many different types.

Here's what it would might look like in Haskell:

    
    
        calculateTaxes :: (OrderItems a, Address a) => a -> [CalculatedTax]

~~~
chown
How should one call or use it? Any example or a link?

~~~
jb55
<https://gist.github.com/1313735>

Here's a full example in some production code. I ended up doing it this way to
simplify some crazy legacy code. There were a bunch of different classes that
provide order items and extended prices in different ways. With this setup as
long as those types implement the necessary interfaces, they get those
extension methods for free.

------
rnemo
I would hope most C# developers are aware of most of these features and how
they facilitate the writing of good C# code, but this article seems like a
good jumping off point for gaining greater understanding of the nuances of C#.

A better title to this article would have been "Less Understood Features of
C#," as things like nullable types, boxing and unboxing using as/is, readonly
variables, Nullable<T>, type inferrence and most of the rest of the articles
content should not be hidden to anyone who intends to have more than passing
knowledge of the language. Most of the things mentioned by the post benefit
from having the additional explanation so they can be understood well though.

------
MatthewPhillips
One of the features not listed here is a little talked about (or perhaps just
overlooked by me) feature of 4.0, covariance and contravariance.[1] One of the
annoying things I've always had to deal with on collection classes is knowing
that an instance implements some interface (because it is where T :
ISomeInterface) but having to cast the collection in methods. 4.0 fixes that
with the <out T> directive. I still haven't completely wrapped my head around
the concepts but they seem pretty powerful to me.

[1]<http://msdn.microsoft.com/en-us/library/dd799517.aspx>

~~~
tkellogg
It took me a while to understand it because it requires you to think
differently about methods & types. Basically, a method can have inputs
(parameters) and outputs (return values). So if you have an interface:

    
    
        public void IEnumerable<T>
        {
          IEnumerator<T> GetEnumerator();
        }
    
    

The T type is only used in outputs in all the members. Therefore it can be
declared with the `out` directive (i.e. public void IEnumerable<out T>).
Covariance & contravariance doesn't work with classes, only with interfaces &
delegates. Consider this delegate:

    
    
        public delegate void Action<in T>(T obj);
    

This can be declared with covariance (the in directive) because it only uses T
in it's inputs. So an Action<string> can be passed into a method that takes
Action<object>.

Also, note that this doesn't work with T Func<T>(T obj) because it takes T as
input & returns it (output). However, it does work with TReturn Func<in T, out
TReturn>(T obj) because neither T nor TReturn is taken as both input & output.

Does this make more sense? It's a hard concept to fully understand

------
apetrovic
Hidden features? Really? yield, ?? operator, @ "operator" for raw strings,
nullable types, etc, are considered as "hidden" / advanced features?

I don't want to sound snobbish, but at least 90% of that list I consider as a
basic C# knowledge. If you don't know how to make an enumerable with yield, or
insert some debug code with DEBUG or guard resource with using(), what exactly
you know?

~~~
jacabado
I didn't knew how to make an enumerable with an yield.

[http://csharpindepth.com/Articles/Chapter11/StreamingAndIter...](http://csharpindepth.com/Articles/Chapter11/StreamingAndIterators.aspx)

I had used it to make a state machine but didn't know its relation to
IEnumerable. The article was enlightening to a C# latecomer like me.

------
InclinedPlane
Using blocks don't seem to be getting enough love, imo.

Instead of writing this pattern all the time:

    
    
      StreamWriter writer = null;
      try {
        writer = new StreamWriter(filename);
        // etc.
      } finally {
        if (writer != null) {
          writer.Close();
        }
      }
    

You can just write this:

    
    
      using (StreamWriter writer = new StreamWriter(filename)) {
        // etc.
      }
    

Which does exactly the same thing.

~~~
MatthewPhillips
What's the point in a try without a catch?

~~~
stevecooperorg
the finally block is always executed, then the exception is thrown. So

    
    
        try { dobadthing(); }
        finally { cleanup(); }
    

calls dobadthing(), which throws an exception; then cleanup() is called in
case some recovery can be done, then the exception is thrown as if there were
no try block.

~~~
MatthewPhillips
Yes, I understand how finallys work. I was questioning why you wouldn't want
to catch dobadthing().

~~~
maximilianburke
IMO the big benefit of 'using' statements is that they have the ability to
incorporate RAII-type semantics (the idea of scoped resource lifetimes) into
C#, which normally doesn't have them, via objects that implement the
IDisposable interface. It can make it cleaner and less error-prone to have the
language perform cleanup for you automatically than relying on the user to do
so himself.

~~~
noblethrasher
AS I argued elsewhere[1], exploiting the way C# handles `foreach` is a better
way of achieving RAII IMHO; it forces the client code to do the right thing
rather than hoping it will remember to use the `using` statement (or manually
call Dispose()).

[1]<http://news.ycombinator.com/item?id=3423426>

~~~
bunderbunder
Cost of not disposing isn't really high enough to be worth such code-
obfuscating contortions.

The garbage collector makes sure objects are properly disposed of. The only
real cost to letting the collector handle it is that the object ends up
surviving for an extra GC cycle. It's sloppy practice, and it means memory
consumption will be higher if your program rapidly generates a lot of short-
lived IDisposables, but otherwise the difference will probably be trivial.

~~~
noblethrasher
I'm not saying to avoid IDisposable (just the opposite in fact).

The `foreach` statement and the `using` statement just so happen to desugar to
similar code when it comes to handling IDisposable. The C# compiler will
guarantee that Dispose() is called on the iterator and that code in the
`finally` block will execute... even if you exit the loop early due to an
`exception` or a break/goto. Just like the `using` statement.

The benefit is that it's even more of a pit-of-success feature than the
`using` statement because you can't possibly forget to call Dispose().

It's also only slightly more work for the library author and slightly less
work for the client but the client is going to use the code many more times
than the author will write it.

------
Hominem
Useful for The DebuggerStepthrough attribute! I have been thinking that such a
feature must exist but hadn't gotten around to looking it up.

Otherwise yeah, no real surprises. Except maybe the Generic aliases.

~~~
politician
DebuggerStepThrough is really useful, but only use it on code you are 100%
sure is correct; otherwise, you're in for a difficult and frustrating debug
session 6 months later.

------
wimpycofounder
Most of those things are hardly hidden. Null coelescence operator? Pre
processor directives? I certainly wouldn't call those hidden features...

------
mikescar
I'd like to see one of these for PHP, we don't have the larger C++ world
immediately available, but it would still be interesting.

~~~
gtani
(Questions closed, but 79 answers)

[http://stackoverflow.com/questions/tagged/hidden-
features?so...](http://stackoverflow.com/questions/tagged/hidden-
features?sort=votes&pagesize=50)

------
SonicSoul
there are 2 books that give great insight into c# features and usage:

"Effective C#", and "More Effective C#"

~~~
cjg_
I would recommend "C# in Depth" by Jon Skeet also.

