6 ms·
Hidden features of C#
- rnemo 15y agoI 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.
- Hominem 15y agoUseful 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.
- sams99 15y agoDebuggerStepthrough has its limitations, this one is pretty big: http://stackoverflow.com/questions/8751814/can-debuggerstepthrough-be-inherited-into-the-automatically-generated-ienumerabl http://stackoverflow.com/questions/8751814/can-debuggerstept...
- politician 15y agoDebuggerStepThrough 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 15y agoMost of those things are hardly hidden. Null coelescence operator? Pre processor directives? I certainly wouldn't call those hidden features...
- mikescar 15y agoI'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 15y ago(Questions closed, but 79 answers) http://stackoverflow.com/questions/tagged/hidden-features?sort=votes&pagesize=50 http://stackoverflow.com/questions/tagged/hidden-features?so...
- MatthewPhillips 15y agoOne 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 http://msdn.microsoft.com/en-us/library/dd799517.aspx
- tkellogg 15y agoIt 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
- jb55 15y agoOne 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 15y agoHow should one call or use it? Any example or a link?
- jb55 15y agohttps://gist.github.com/1313735 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.
- mattmanser 15y agoSimply: orderItems.CalculateTaxes(); If orderItems implements IOrderItems. Just have to include a using statement for the namespace it's in, it's an extension method. Look them up if you're unsure. I didn't know you could do that with them, it's pretty cool. Although it's kinda what abstract classes and inheritance is for, but you can only inherit from one in C#.
- sreque 15y agoTo be fair, this doesn't really simulate type classes, it's just allowing you to specify in a method signature that a particular type implements more than one interface. To simulate type classes, you would have to have the ability to declare statically that an existing type, potentially one you have no control over, implements an interface, and to then have the static extension methods apply to that type automatically. This is in effect what Scala's implicits do that allows them to simulate type classes.
- RShackleford 15y agokenan doğlununda starında amına korum, orospu çocukları.
- SonicSoul 15y agothere are 2 books that give great insight into c# features and usage: "Effective C#", and "More Effective C#"
- cjg_ 15y agoI would recommend "C# in Depth" by Jon Skeet also.
- apetrovic 15y agoHidden 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 15y agoI didn't knew how to make an enumerable with an yield. http://csharpindepth.com/Articles/Chapter11/StreamingAndIterators.aspx http://csharpindepth.com/Articles/Chapter11/StreamingAndIter... 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.
- blangblang 15y agoI agree that 'hidden' isn't exactly an accurate description, but that is a pretty good list of keywords that commonly get reinvented by less experienced C#-ers. It would be more accurately described as a list of underused idioms, but the title doesn't really detract from its value.
- InclinedPlane 15y agoUsing 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.
- nreece 15y agoThe TRY-CATCH will still be required. USING will only dispose the object.
- politician 15y agoI encourage you to download a copy of Reflector or dotPeek; a using statement is compiled into a try-finally with a null-checked call to Dispose.
- nreece 15y agoI meant, it doesn't really CATCH the error. You can't handle the error, just avoid it being thrown.
- skrebbel 15y agoIt's not an error, it's an exception. Also, the whole point of the original comment was to not catch the exception, but to have it pass down the stack, while providing safe cleanup anyway.
- nreece 15y agoException it is. And how does it pass down the stack? There won't be any trace of it without it being caught.
- 15y ago