share
Stack OverflowHidden Features of C#?
[+1473] [296] Serhat Ozgel
[2008-08-12 16:32:24]
[ c# hidden-features ]
[ https://stackoverflow.com/questions/9033/hidden-features-of-c ]

This came to my mind after I learned the following from this question [1]:

where T : struct

We, C# developers, all know the basics of C#. I mean declarations, conditionals, loops, operators, etc.

Some of us even mastered the stuff like Generics [2], anonymous types [3], lambdas [4], LINQ [5], ...

But what are the most hidden features or tricks of C# that even C# fans, addicts, experts barely know?

Here are the revealed features so far:


Keywords

Attributes

Syntax

Language Features

Visual Studio Features

Framework

Methods and Properties

Tips & Tricks

Other

[+751] [2008-08-13 01:53:50] ageektrapped

This isn't C# per se, but I haven't seen anyone who really uses System.IO.Path.Combine() to the extent that they should. In fact, the whole Path class is really useful, but no one uses it!

I'm willing to bet that every production app has the following code, even though it shouldn't:

string path = dir + "\\" + fileName;

1
[+583] [2008-08-26 18:34:44] chakrit

lambdas and type inference are underrated. Lambdas can have multiple statements and they double as a compatible delegate object automatically (just make sure the signature match) as in:

Console.CancelKeyPress +=
    (sender, e) => {
        Console.WriteLine("CTRL+C detected!\n");
        e.Cancel = true;
    };

Note that I don't have a new CancellationEventHandler nor do I have to specify types of sender and e, they're inferable from the event. Which is why this is less cumbersome to writing the whole delegate (blah blah) which also requires you to specify types of parameters.

Lambdas don't need to return anything and type inference is extremely powerful in context like this.

And BTW, you can always return Lambdas that make Lambdas in the functional programming sense. For example, here's a lambda that makes a lambda that handles a Button.Click event:

Func<int, int, EventHandler> makeHandler =
    (dx, dy) => (sender, e) => {
        var btn = (Button) sender;
        btn.Top += dy;
        btn.Left += dx;
    };

btnUp.Click += makeHandler(0, -1);
btnDown.Click += makeHandler(0, 1);
btnLeft.Click += makeHandler(-1, 0);
btnRight.Click += makeHandler(1, 0);

Note the chaining: (dx, dy) => (sender, e) =>

Now that's why I'm happy to have taken the functional programming class :-)

Other than the pointers in C, I think it's the other fundamental thing you should learn :-)


2
[+527] [2008-08-19 05:43:53] jfs

From Rick Strahl [1]:

You can chain the ?? operator so that you can do a bunch of null comparisons.

string result = value1 ?? value2 ?? value3 ?? String.Empty;
[1] http://www.west-wind.com/weblog/posts/236298.aspx

3
[+453] [2008-09-16 16:53:37] BlackTigerX

Aliased generics:

using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>;

It allows you to use ASimpleName, instead of Dictionary<string, Dictionary<string, List<string>>>.

Use it when you would use the same generic big long complex thing in a lot of places.


4
[+437] [2008-08-15 11:06:48] jfs

From CLR via C# [1]:

When normalizing strings, it is highly recommended that you use ToUpperInvariant instead of ToLowerInvariant because Microsoft has optimized the code for performing uppercase comparisons.

I remember one time my coworker always changed strings to uppercase before comparing. I've always wondered why he does that because I feel it's more "natural" to convert to lowercase first. After reading the book now I know why.

[1] https://rads.stackoverflow.com/amzn/click/com/0735621632

(254) When you "convert a string to upper case" you create a second temporary string object. I thought that this kind of comparison was not preferred, that the best way was: String.Equals(stringA, stringB, StringComparison.CurrentCultureIgnoreCase) whcih does not create this throwaway string at all. - Anthony
(32) What kind of optimization can you perform on comparing upper case strings that can't be done on lower case strings? I don't understand why one would be more optimal than the other. - Parappa
(1) Ran a quick test. Compared "XXX" to "XxX" 1 million times, three ways (no conversion, invariant, and string.Equals). Here are the results: No Match Test: Got 0 matches in 1 ms Invariant Match Test: Got 100000 matches in 23 ms string.Equals Match Test: Got 100000 matches in 8 ms - dviljoen
(1) I just use string.Compare(strA, strB, true) for a culture invariant-non case sensitive comparison, no need to convert both string to upper (it's probably done by the compiler much more efficiently). - Ricardo Villamil
(36) Converting to uppercase rather than lowercase can also prevent incorrect behavior in certain cultures. For example, in Turkish, two lowercase i's map to the same uppercase I. Google "turkish i" for more details. - Neil
(2) @neilwhitaker1: That is not an issue when using invariant conversions. - Rasmus Faber
(34) I tried benchmarking ToUpperInvariant vs ToLowerInvariant. I cannot find any difference in their performance under .NET 2.0 or 3.5. Certainly not anything that warrant "highly recommending" using one over the other. - Rasmus Faber
(1) Don't question the mighty Jeffrey Richter! :P Although for probably 90% of applications by SO developers this will make a tiny difference. - Chris S
(19) ToUpperInvariant is preferred because it makes all characters round-trip. See msdn.microsoft.com/en-us/library/bb386042.aspx. For comparisons, write"a".Equals("A", StringComparison.OrdinalIgnoreCase) - SLaks
I think turkey i is the only reason to be concerned here, most likely your call to ToUpper is not in a critical path and worrying about it would be premature optimization. If you found out it was, you can easily fix it then. However, since this affects the turkey i problem, I would insist on using ToUpper even if it were slower. - Adam Luter
(2) @neilwhitaker1: it's not true that in turkish both i's map the same uppercase letter, they both map to different upper case letters. So I don't see why uppercase would be better then lowercase. - pauloya
(7) in Turkish, mapping is (i -> İ) and (ı -> I). So "files".ToUpper() != "FILES" and similarly "FILES".ToLower() != "files". That's why you need to use ToUpperInvariant() or ToLowerInvariant() in certain cases. - Sedat Kapanoglu
FYI - If you're doing string comparisons for security purposes consider reading this post: leastprivilege.com/… - TLDR
(2) The way I read the Richter quote, he's saying that comparisons between upper case strings are optimised. NOT that converting to upper is any more efficient than converting to lower. - Dominic Cronin
(1) Have to go with @Anthony here, just tell the comparison function what you want it to do, it's optimized already anyway -- not leveraging the frameworks built-in features to roll your own is just ridiculous. - BrainSlugs83
5
[+407] [2008-09-12 13:25:55] user1228

My favorite trick is using the null coalesce operator [1] and parentheses to automagically instantiate collections for me.

private IList<Foo> _foo;

public IList<Foo> ListOfFoo 
    { get { return _foo ?? (_foo = new List<Foo>()); } }
[1] http://en.wikipedia.org/wiki/%3F%3F_Operator

(3) Now that is a cool technique: in-lining the assignment when null! - andleer
(23) Don't you find it hard to read? - Riri
(72) Its slightly hard to read for the noo... er, inexperienced. But its compact and contains a couple patterns and language features that the programmer should know and understand. So, while it is hard at first, it provides the benefit of being a reason to learn. - user1228
(38) Lazy instantiation is somewhat malpractice because it's a poor mans choice to avoid thinking about class invariants. It also has concurrency issues. - John Leidegren
(2) I usually use it as .. return _foo = _foo ?? new List<Foo>(); ... IMO a little easier to read. - chakrit
Sorry, misread what you wrote @chakrit... Its not bad, but it doooes take about 2 ms more to execute yours... - user1228
(17) I've always been informed this is bad practise, that calling a property should not do something as such. If you had a set on there and set the value to null, it would be very strange for someone using your API. - Ian
(2) @Ian: I suppose if I tracked down and beat up anybody using my API that would also be very strange to anyone using it. Perhaps I'll strike that from my "foolish things that anybody with sense wouldn't do but seem like a pretty cool idea to me" list. I just can't fathom what your comment has to do with anything. It boggles my mind. "If you did something stupid it would be stupid." I suppose it makes sense, but why would I? I'm so confused. - user1228
@Will: what I think Ian is referring too is this: calling ListOfFoo influences the internal state of your class. User A of your API, who calls ListOfFoo before FunctionThatDoesSomethingWithFoo, might see a different behaviour than User B, who calls FunctionThatDoesSomethingWithFoo without calling ListOfFoo first. - jan
(6) @jan I'm not sure how that is. The behavior outside of the body of the 'get' is the same. Are you referring to the practice of bypassing the public property when accessing it within the class? I consider that bad practice, personally. Still, Ian says that IF I had a setter it would be bad; yes, and if I hit my head with a hammer it would be bad also, that's why I don't. So I'm still confused about his concerns. BRB, not jumping off a cliff naked. - user1228
(1) +1 for this. However its worth looking at the revision history of this answer. There is a good point about being careful with the syntax of this so you get the object instance back you think you will. check it out - Matt
(2) I think Ian's point about the setter is well made: if I am using the class and use a setter to set ListOfFoo to null, the fact that it would be non-null the next time I call it is breaking expectations of how a property should behave. So it is correct to point out that this pattern should not be used with a setter. - Joel in Gö
(8) @Joel except that setting ListOfFoo to null is neither part of the class contract nor is it good practice. That's why there isn't a setter. Its also why ListOfFoo is guaranteed to return a collection and never a null. Its just a very odd complaint that if you do two bad things (make a setter and set a collection to null) this will result in your expectations being wrong. I wouldn't suggest doing Environment.Exit() in the getter, either. But that also has nothing to do with this answer. - user1228
(2) @Will I don't think this is hard to read at all, and I'm not even a C# programmer. However, I still think this is not really good practice for a property. What's the gain of the lazy initialization? Not much. Why complicate the state space of the object for no good reason? The feature itself is neat (although I'm not sure how the evaluation of an expression is considered a hidden feature...), but I think this particular application is a bit of a bad idea. - TM.
@Charlie Flowers, putting initializer code in a getter is a Ruby standard practice (Ruby idiom)?! - James
@James, I can't tell if you're asking me or telling me. But yes, it is a standard idiom in Ruby. Particularly for checking if the value is null because it has not been initialized yet. So it's lazy initialization, and probably more importantly it minimizes the amount of boilerplate needed to define a property and get it working. - Charlie Flowers
(1) Another vote for not allowing API users to reassign collections in most circumstances. Also wanted to agree that you should be using your own properties in your class methods, not accessing the private fields directly. Still, I generally prefer to ensure the existence of a collection with readonly initialization, unless the list needs to be lazy-loaded. - Isabelle Wedin
I do this all the time... but interesting side note... reflector can't figure it out! Try reflecting an assembly in which you did this, and it'll tell you that the code was obfuscated ;) (at least it did before I quit my .Net job to start my own company...) - John Gibb
(1) What if you have a race condition to this property? It may cause double initialization the field, each thread getting a different copy. That's not good. This is not a failure of the operatior, may be using lock? read-write lock? interlocked? a nested class? Lazy<T>? - Theraot
@Theraot: Yes, this is not thread safe. Of course, if you expect to be accessing this from multiple threads, you might want to try something different, such as what you stated. - user1228
(3) @Theraot Wouldn't Lazy<T> be a better idea anyway? - riezebosch
@riezebosch, I did mention it, didn't I? Left last for dramatic effect or just because I was unable to use .NET 4 in production at the time... (it has to do with mono and linux). Apart from Lazy<T> the other has their place too although this is not a good place to discuss that. - Theraot
Not thread safe, hard to read, confusing when used with a setter. This is no good. - tmaj
6
[+314] [2008-08-12 21:57:39] andynil

Avoid checking for null event handlers

Adding an empty delegate to events at declaration, suppressing the need to always check the event for null before calling it is awesome. Example:

public delegate void MyClickHandler(object sender, string myValue);
public event MyClickHandler Click = delegate {}; // add empty delegate!

Let you do this

public void DoSomething()
{
    Click(this, "foo");
}

Instead of this

public void DoSomething()
{
    // Unnecessary!
    MyClickHandler click = Click;
    if (click != null) // Unnecessary! 
    {
        click(this, "foo");
    }
}

Please also see this related discussion [1] and this blog post [2] by Eric Lippert on this topic (and possible downsides).

[1] https://stackoverflow.com/questions/840715/the-proper-way-of-raising-events-in-the-net-framework
[2] http://blogs.msdn.com/ericlippert/archive/2009/04/29/events-and-races.aspx

Interesting tip! Personally, I use helper extension methods from my project (codeplex.com/thehelpertrinity) to simply do this: Click.Raise(this, "foo"); - Kent Boogaart
(87) I believe a problem will appear if you rely on this technique and then you have to serialize the class. You will eliminate the event, and then on deserialization you will get a NullRefference.... .So one can just stick to the "old way" of doing things. It's safer. - sirrocco
(16) you can still set your event handler to null, so you can still get a null reference, and you still have a race condition. - Robert Paulson
(4) Also, performance-wise, it has to call an empty method every time. - TraumaPony
(2) I really don't like that this approach gets so much attention. The performance hit you take is actually somewhat substantial. - senfo
The performance hit of an exception that would be generated by a null reference would be greater than an empty delegate. I like the tip. Of course, doing an if-check on the delegate would be the fastest, but its still an elegant solution to a common problem. - dviljoen
(2) If I understand it correctly, this forces any subscribed-to events to be multicast instead of singlecast, with a big performance hit as a result. It also forces an invoke on events that would otherwise not have to be called, another big hit. Not worth the tiny bit of typing it saves! - P Daddy
(64) A quick profile test shows that dummy-subscribed event handler without null test takes roughly 2x the time of unsubscribed event handler with null test. Multicast event handler without null test takes about 3.5x the time of singlecast event handler with null test. - P Daddy
(4) I don't know why this looks so elegant, looks like a hack to me...for that same reason, then why not assign all objects to something, instead of checking to null before using them? Besides, I agree with P Daddy, the performance hit is not worth the savings in typing. - Ricardo Villamil
(54) This avoids the need for a null check by just always having a self-subscriber. Even as an empty event this carries an overhead that you don't want. If there are no subscribers you don't want to fire the event at all, not always fire an empty dummy event first. I would consider this bad code. - Keith
This is a great tip. To the developers that like checking every reference for null, STOP IT! Only check a reference for null if you expect that it might be null FOR A GOOD REASON! - Sean
(2) Can someone with rep modify the post, to include information about the performance cost? Not everyone reads the comments. - Nate Parsons
(56) This is a terrible suggestion, for the reasons in the above comments. If you must make your code look "clean", use an extension method to check for null then call the event. Someone with modify privileges should definitely add the cons to this answer. - Greg
(2) You shouldn't modify the answer without very good reason. Downvote the answer if you believe it's no good. Others obviously think it is. - Josh Smeaton
It's also suspect because a class user might set the event to null, removing your "self-subscribed" handler and causing issues. And the "instead of" code was bad. That, at least, I could just fix. - Joel Coehoorn
(3) Also see this post for more details and alternatives: blogs.msdn.com/ericlippert/archive/2009/04/29/… - Joel Coehoorn
I prefer using extension methods for event firing, I use a slightly modified (for increased thread safety) version of the technique at elegantcode.com/2007/12/05/firing-events-with-extension-meth‌​ods - Phil Price
(11) the "you don't want to fire it at all" argument is BS. The check should clearly be confined to the event infrastructure, and not the user. It is a language misdesign, which should rather be fixed. Empty subscriber list is a valid subscriber list! Zero is a number, and black is a color. - Pavel Radzivilovsky
(4) Pavel is right in saying that this should never have been an issue in the first place. This should have been designed into the language. What possible reason is there for an event to be null? That said, adding an empty delegate is a less-than-ideal solution. An extension method is better, but it is still best-practice to create an invoker method, so that you can more easily control access to the event. For example, if you decide to allow child classes to raise the event, you can simply make the invoker method protected. The extension method should aid in writing invokers--not replace them. - StriplingWarrior
(1) @Pavel, I 100% agree with you, I can never imagine a situation that you would want an event to be "null" instead of an empty list. The funny thing is that in VB.NET it is actually like you say already. So it's really weird that it's not like that in C#. - Matthijs Wessels
There should have been such a function built into the framework. - supercat
I use an extension method Raise<T>(this EventHandler<T> handler, object sender, EventArgs<T> args) that does a check against null in its body -- that way I can just write MyEvent.Raise(this, args) without needing to care about the check. - efdee
I often do this with an empty lambda: public event MyClickHandler Click = (a, b) => { }; - Justin Morgan
In the end the only high performance way is the original. Empty delegates are a hit, single empty subscriber is a hit, an extension method is a hit. Doing the null check within the code itself is the fastest method. - Nick Bedford
How is extension method a hit? 1 function call :-) - Kugel
I wish the null check could be generated by compiler. - brgerner
7
[+304] [2008-08-12 18:23:40] Keith

Everything else, plus

1) implicit generics (why only on methods and not on classes?)

void GenericMethod<T>( T input ) { ... }

//Infer type, so
GenericMethod<int>(23); //You don't need the <>.
GenericMethod(23);      //Is enough.

2) simple lambdas with one parameter:

x => x.ToString() //simplify so many calls

3) anonymous types and initialisers:

//Duck-typed: works with any .Add method.
var colours = new Dictionary<string, string> {
    { "red", "#ff0000" },
    { "green", "#00ff00" },
    { "blue", "#0000ff" }
};

int[] arrayOfInt = { 1, 2, 3, 4, 5 };

Another one:

4) Auto properties can have different scopes:

public int MyId { get; private set; }

Thanks @pzycoman for reminding me:

5) Namespace aliases (not that you're likely to need this particular distinction):

using web = System.Web.UI.WebControls;
using win = System.Windows.Forms;

web::Control aWebControl = new web::Control();
win::Control aFormControl = new win::Control();

I've actually needed to do the first one on a project using Anthem, because it clobbers the WebControls namespace. - Adam Lassek
(14) in #3 you can do Enumerable.Range(1,5) - Echostorm
Yeah, you can for that specific example, maybe it was poorly chosen. You can init any array in this way: int[] arrayOfInt = new { 4, 8, 15, 16, 23, 42 } - Keith
(18) i think you've been able to initialize arrays with int[] nums = {1,2,3}; since 1.0 :) doesn't even need the "new" keyword - Lucas
You can, but now you can also do this: var lst = new List<int> { 4, 8, 15, 16, 23, 42 } - Keith
(13) also lambda without parameters ()=> DoSomething(); - Pablo Retyk
I weep for auto properties not getting default values - Chad Grant
@3) int[] arrayOfInt = new { 1, 2, 3, 4, 5 }; I even more like var[] intArray=new {1,12,14}; @4) Unfortunately, only 'get;private set;' works, any other combination like 'get; internal set;' is not possible :O( Better than nothing but not perfectly consistent IMHO, though this is rather syntactical sugar and no fundamental language ability - Simon D.
(5) I've used both { get; internal set; } and { get; protected set; }, so this pattern is consistent. - Keith
@Keith: +1 for this correction, I was mislead by someone stating this. In fact, one can chose various access modifiers for either get or set. The real restriction is that you cannot use one for get AND one for set (makes sense because then one should change the access modifier of the property instead of the accessors) - Simon D.
The namespaces aliases remind me of the yucky c++ :-S - Andrei Rînea
Ooo, I like this application of Enumerable.Range() which looks cleaner: new way:______________ foreach (int i in Enumerable.Range(1, 100)) { Console.WriteLine(i); } old way:_______________ for (int i = 1; i <= 100; i++) { Console.WriteLine(i); } - BrokeMyLegBiking
@BrokeMyLegBiking - actually I would keep the for loop in that case - the foreach would be slower and more confusing. The Enumerable.Range is most useful for initialising collections without a countered loop. If you're going to loop anyway it's best to stick with for - Keith
or web.Control aWebControl = new web.Control(); - Kirk Broadhurst
(7) @Kirk Broadhurst - you're right - new web.Control() would also work in this example. The :: syntax forces it to treat the prefix as a namespace alias, so you could have a class called web and the web::Control syntax would still work, while the web.Control syntax wouldn't know whether to check the class or the namespace. Because of that I tend to always use :: when doing namespace aliases. - Keith
this last namespace trick is really useful to override an existing one. See on my blog for example! alsagile.com/archive/2010/03/09/… - Stéphane
You can have as many parameters to your lambdas as you'd like: (n1,n2,n3) => n1+n2+n3; - L. Kolmodin
@L. Kolmodin - yeah you can - my 2nd point is that when you just have 1 you can skip the parameters: (x) => becomes x => - Keith
//Duck-typed: works with any .Add method. var colours = new Dictionary<string, string> { { "red", "#ff0000" }, { "green", "#00ff00" }, { "blue", "#0000ff" } }; int[] arrayOfInt = { 1, 2, 3, 4, 5 }; this is not duck typing! - Lukasz Madon
@lukas - this is syntactic sugar, but under the hood it works on any class that implements a method like void Add(...) - that includes your own classes without the need to implement an interface. I agree that on the int[] it's C# syntax, but that it works for any type with an Add method is duck-typing - Keith
@"1) implicit generics (why only on methods and not on classes?)" -- this can be alleviated for constructor calls through wrapping the constructor like this: class C<A,B> { public C(A a, B b) { ... } } static class C { public C<A,B> New<A,B>(A a, B b) { return new C<A,B>(A a, B b); } class Main { public void main() { var c = C.New(someA,someB); // type params inferred } - FunctorSalad
@FunctorSalad - I know, which makes it even less logical that you can't, see my question on it: stackoverflow.com/questions/45604 - Keith
(1) @Keith and @lukas: it is duck-typing but you also have to implement System.Collections.IEnumerable. You can get really crazy with void Add overload: new MyClass { 1, "a", { 1, "a" } };. See this question - HuBeZa
@HuBeZa - good point, I guess that's because Add on its own could mean something else, so List<int> x = new List<int>{1, 2, 3, 4, 5 } should collection initialise and makes sense. However int has an Add method but int x = new int{1, 2, 3, 4, 5} makes no sense. - Keith
Number 3: But this doesn't work : byte[] get_bytes(){return {};}!!! - lmat - Reinstate Monica
@LimitedAtonement sorry, it's a little confusing. The { syntax for add doesn't work when the collection is empty. - Keith
8
[+285] [2008-08-12 16:42:04] Mike Stone

I didn't know the "as" keyword for quite a while.

MyClass myObject = (MyClass) obj;

vs

MyClass myObject = obj as MyClass;

The second will return null if obj isn't a MyClass, rather than throw a class cast exception.


(42) Don't over-do it though. Lots of people seem to use as because the prefer the syntax even though they want the semantics of a (ToType)x. - Scott Langham
Yes, what's specified in this answer is only one of the differences between (ToType) and "as ToType". - bzlm
The "as" keyword also offers better performance :-) - Dan Herbert
(4) I don't believe it offers better performance. Have you profiled it? (Obviously though it does when the cast fails... but when you use (MyClass) cast, failures are exceptional.. and extremely rare (if they happen at all), so it makes no difference. - Scott Langham
(7) This is only more performant if the usual case is the cast failing. Otherwise the direct cast (type)object is faster. It takes longer for a direct cast to throw an exception than to return null though. - Spence
(15) Right along the same lines of the "as" keyword... the "is" keyword is just as useful. - dkpatt
(1) It should be noted that this only works on nullable classes. You have to use int? instead of int. - Dan McClain
(28) You can abuse it and have a NullReferenceException down your road later when you could have had a InvalidCastException earlier. - Andrei Rînea
@spence: +10. Many people don't realize that if the cast is more than likely to succeed, using 'as' will reduce performance compared to a direct cast. - Steven Evers
(1) @SnOrfus @Spence have you profiled the performance of the two cast methods in a recent CLR version? I didn't see any performance difference between the two when they succeeded. - James Schek
Here's some inside info on the matter: "The specification is clear on this point; as (in the non-dynamic case) is defined as a syntactic sugar for is. However, in practice the CLR provides us instruction isinst, which ironically acts like as"blogs.msdn.com/b/ericlippert/archive/2010/09/16/… - gjvdkamp
as and casts are implemented differently, so the choice is more than just a matter of taste. See stackoverflow.com/questions/6099617/… - Tor Haugen
9
[+261] [2008-08-13 07:39:13] lomaxx

Two things I like are Automatic properties so you can collapse your code down even further:

private string _name;
public string Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

becomes

public string Name { get; set;}

Also object initializers:

Employee emp = new Employee();
emp.Name = "John Smith";
emp.StartDate = DateTime.Now();

becomes

Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()}

This makes classes much quicker to write. - David Basarab
(6) Should it be noted that Automatic Properties are a C# 3.0 only feature? - Jared Updike
The great thing is typing "Prop" 2x[tab] and you get the property for free :) - Boris Callens
(21) Automatic Properties were introduced with the 3.0 compiler. But since the compiler can be set to output 2.0 code, they work just fine. Just don't try to compile 2.0 code with automatic properties in an older compiler! - Joshua Shannon
(74) Something many people don't realise is that get and set can have different accessibility, eg: public string Name { get; private set;} - Nader Shirazie
(7) Only problem with Automatic Properties is that it doesn't seem to be possible to provide a default initialization value. - Stein Åsmul
NValidate doesn't like automatic properties... - Mike Kingscott
...I always provide default values for Automatic Properties in my constructor. Will look into the DefaultValue attribute! - Funka
(7) @ANeves : no it's not. From that page: A DefaultValueAttribute will not cause a member to be automatically initialized with the attribute's value. You must set the initial value in your code. [DefaultValue] is used for the designer so it knows whether to show a property in bold (meaning non-default). - Roger Lipscombe
(1) @Roger Lipscombe: thanks plenty for the correction. You are absolutely right - msdn.microsoft.com/en-us/library/… - ANeves
About the default value: you could write a base class that sets the default prop values from the DefaultValueAttribute via reflection in the constructor, but there would be a performance loss obviously - Guillaume86
@Guillaume86: I actually did that for a certain class hierarchy where I was using an Option type (in C#). Obviously Option types should initialize to None (the whole point is that they should be non-nullable). My base class constructor inspected the object for Option type properties and initialized them all to None. - Scott Whitlock
10
[+254] [2008-08-13 10:20:07] Eric Minkes

The 'default' keyword in generic types:

T t = default(T);

results in a 'null' if T is a reference type, and 0 if it is an int, false if it is a boolean, etcetera.


(4) Plus: type? as a shortcut for Nullable<type>. default(int) == 0, but default(int?) == null. - sunside
11
[+225] [2008-08-12 16:59:40] Stu

Attributes in general, but most of all DebuggerDisplay [1]. Saves you years.

[1] http://msdn.microsoft.com/en-us/library/x810d419.aspx

(9) Using DebuggerDisplay Attribute (MSDN): msdn.microsoft.com/en-us/library/x810d419.aspx - Jon Adams
12
[+220] [2008-08-13 02:07:26] lomaxx

The @ tells the compiler to ignore any escape characters in a string.

Just wanted to clarify this one... it doesn't tell it to ignore the escape characters, it actually tells the compiler to interpret the string as a literal.

If you have

string s = @"cat
             dog
             fish"

it will actually print out as (note that it even includes the whitespace used for indentation):

cat
             dog
             fish

wouldn't the string include all the spaces that you used for indentation? - andy
(18) Yes it's called verbatim string. - Joan Venge
(4) It would be clearer if the output showed the spaces that would be printed out as well. Right now it seems as if the new lines characters are printed but spaces are ignored. - aleemb
Very useful for escaping regular expressions and long SQL queries. - ashes999
It also maps {{ to { and }} to } making it useful for string.Format(). - Ferruccio
13
[+219] [2008-09-09 21:52:00] Jason Olson

I think one of the most under-appreciated and lesser-known features of C# (.NET 3.5) are Expression Trees [1], especially when combined with Generics and Lambdas. This is an approach to API creation that newer libraries like NInject and Moq are using.

For example, let's say that I want to register a method with an API and that API needs to get the method name

Given this class:

public class MyClass
{
     public void SomeMethod() { /* Do Something */ }
}

Before, it was very common to see developers do this with strings and types (or something else largely string-based):

RegisterMethod(typeof(MyClass), "SomeMethod");

Well, that sucks because of the lack of strong-typing. What if I rename "SomeMethod"? Now, in 3.5 however, I can do this in a strongly-typed fashion:

RegisterMethod<MyClass>(cl => cl.SomeMethod());

In which the RegisterMethod class uses Expression<Action<T>> like this:

void RegisterMethod<T>(Expression<Action<T>> action) where T : class
{
    var expression = (action.Body as MethodCallExpression);

    if (expression != null)
    {
        // TODO: Register method
        Console.WriteLine(expression.Method.Name);
    }
}

This is one big reason that I'm in love with Lambdas and Expression Trees right now.

[1] http://msdn.microsoft.com/en-us/library/bb397951.aspx

(3) I have a reflection utility class that does the same with FieldInfo, PropertyInfo, etc... - Olmo
Yes, this is great. I was able to use methods like this to write code like EditValue(someEmployee, e => e.FirstName); in my business logic and have it automatically generate all the plumbing logic for a ViewModel and View to edit that property (so, a label with the text "First Name" and a TextBox with a binding that calls the setter of the FirstName property when the user edits the name, and updates the View using the getter). This seems to be the basis for most of the new internal DSLs in C#. - Scott Whitlock
(4) I think these aren't so much lesser-known as lesser-understood. - Justin Morgan
Why do you need to register a method? I have never used this before - where and when would this be used? - MoonKnight
14
[+208] [2008-08-12 16:34:44] Michael Stum

" yield [1]" would come to my mind. Some of the attributes like [DefaultValue()] [2] are also among my favorites.

The " var [3]" keyword is a bit more known, but that you can use it in .NET 2.0 applications as well (as long as you use the .NET 3.5 compiler [4] and set it to output 2.0 code) does not seem to be known very well.

Edit: kokos, thanks for pointing out the ?? operator, that's indeed really useful. Since it's a bit hard to google for it (as ?? is just ignored), here is the MSDN documentation page for that operator: ?? Operator (C# Reference) [5]

[1] http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx
[2] http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
[3] http://msdn.microsoft.com/en-us/library/bb383973.aspx
[4] http://blogs.msdn.com/msbuild/archive/2006/11/03/msbuild-orcas-and-multi-targeting.aspx
[5] http://msdn.microsoft.com/en-us/library/ms173224.aspx

(14) The default value's documentation says it is not really setting the value of the property. It's only a helper for visualisers and code generators. - Boris Callens
(2) As for DefaultValue: In the meantime, some libraries use it. ASP.net MVC uses DefaultValue on Parameters of a Controller Action (Which is very useful for non-nullable types). Strictly speaking of course, this is a code generator as the value is not set by the compiler but by MVC's code. - Michael Stum
(6) The name for the ?? operator is the "Null Coalescing" operator - Armstrongest
yield is my favorite, the coalesce operator is up there though. I don't see anything about CAS, or assembly signing, strong names, the GAC... I suppose only CAS is C#... but so many developers have no clue about security. - BrainSlugs83
15
[+197] [2008-08-12 17:07:59] Brad Barker

I tend to find that most C# developers don't know about 'nullable' types. Basically, primitives that can have a null value.

double? num1 = null; 
double num2 = num1 ?? -100;

Set a nullable double, num1, to null, then set a regular double, num2, to num1 or -100 if num1 was null.

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

one more thing about Nullable type:

DateTime? tmp = new DateTime();
tmp = null;
return tmp.ToString();

it is return String.Empty. Check this [1] link for more details

[1] https://stackoverflow.com/questions/4547112/is-nullable-datetime-work-correct

whats the difference between this and just using the wrapper objects fro primatives? - shsteimer
some types are nullable normally, like DateTime. So, DateTime? is a godsend - mmcdole
(1) DateTime cannot be set to null. - Jason Jackson
(1) This is effectively C# syntactic sugar for Nullable<T>, so is merely possibly by use of generics. - Wim
(2) So then is "int" just C# syntactic sugar for System.Int32 ? There actually is compiler support built around the Nullable types, enabling setting them to null, for instance (which can't be done using generic structs alone), and boxing them as their underlying type. - P Daddy
(4) @P Daddy - yes, int is syntactic sugar for System.Int32. They are completely interchangeable, just like int? === Int32? === Nullable<Int32> === Nullable<int> - cjk
(6) @ck: Yes, int is an alias for System.Int32, as T? is an alias for Nullable<T>, but it isn't just syntactic sugar. It's a defined part of the language. The aliases not only make the code easier to read, but also fit our model better. Expressing Nullable<Double> as double? underscores the perspective that the value thus contained is (or may be) a double, not just some generic structure instantiated on type Double. (continued) - P Daddy
(3) ... In any case, the argument wasn't about aliases (that was just a poor analogy, I suppose), but that nullable types—using whatever syntax you prefer—are indeed a language feature, not just a product of generics. You can't reproduce all the functionality of nullables (comparison to/assignment of null, operator forwarding, boxing of underlying type or null, compatibility with null coalescing and as operators) with generics alone. Nullable<T> alone is rudimentary and far from stellar, but the concept of nullable types as part of the language is kick ass. - P Daddy
had no clue data types that were once hated by null can now work as a null. :D Great to know! - Mike
@Brad Barker: tmp.ToString() returns empty string because it returns "the text representation of the value of the current System.Nullable<T> object if the System.Nullable<T>.HasValue property is true, or an empty string ("") if the System.Nullable<T>.HasValue property is false." - VoodooChild
16
[+192] [2008-08-12 18:50:29] Judah Gabriel Himango

Here are some interesting hidden C# features, in the form of undocumented C# keywords:

__makeref

__reftype

__refvalue

__arglist

These are undocumented C# keywords (even Visual Studio recognizes them!) that were added to for a more efficient boxing/unboxing prior to generics. They work in coordination with the System.TypedReference struct.

There's also __arglist, which is used for variable length parameter lists.

One thing folks don't know much about is System.WeakReference [1] -- a very useful class that keeps track of an object but still allows the garbage collector to collect it.

The most useful "hidden" feature would be the yield return keyword. It's not really hidden, but a lot of folks don't know about it. LINQ is built atop this; it allows for delay-executed queries by generating a state machine under the hood. Raymond Chen recently posted about the internal, gritty details [2].

[1] http://msdn.microsoft.com/en-us/library/ms404247.aspx
[2] http://blogs.msdn.com/oldnewthing/archive/2008/08/12/8849519.aspx

(2) More details on the undocumented keywords by Peter Bromberg. I still don't get if there are reasons to ever use them. - HuBeZa
@HuBeZa with the advent of generics, there aren't many (any?) good reasons to used __refType, __makeref, and __refvalue. These were used primarily to avoid boxing prior to generics in .NET 2. - Judah Gabriel Himango
Matt, with the introduction of generics in .NET 2, there's little reason to use these keywords, as their purpose was to avoid boxing when dealing with value types. See the link by HuBeZa, and also see codeproject.com/Articles/38695/UnCommon-C-keywords-A-Look#ud - Judah Gabriel Himango
17
[+184] [2008-09-23 20:39:01] ZeroBugBounce

Unions (the C++ shared memory kind) in pure, safe C#

Without resorting to unsafe mode and pointers, you can have class members share memory space in a class/struct. Given the following class:

[StructLayout(LayoutKind.Explicit)]
public class A
{
    [FieldOffset(0)]
    public byte One;

    [FieldOffset(1)]
    public byte Two;

    [FieldOffset(2)]
    public byte Three;

    [FieldOffset(3)]
    public byte Four;

    [FieldOffset(0)]
    public int Int32;
}

You can modify the values of the byte fields by manipulating the Int32 field and vice-versa. For example, this program:

    static void Main(string[] args)
    {
        A a = new A { Int32 = int.MaxValue };

        Console.WriteLine(a.Int32);
        Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four);

        a.Four = 0;
        a.Three = 0;
        Console.WriteLine(a.Int32);
    }

Outputs this:

2147483647
FF FF FF 7F
65535

just add using System.Runtime.InteropServices;


(7) @George, works wonders when you are communicating with legacy apps over sockets using c union declarations. - scottm
(2) There's also meaningful to say int and float at offset 0. It's what you need if you want to manipulate floating point numbers as bit masks, which you sometimes want to. Especially if you wanna learn new things about floating point numbers. - John Leidegren
(2) The annoying thing about this is if you're going to use this is a struct the compiler will force you to set ALL the variables in the init function. So if you have: public A(int int32) { Int32 = int32; } it will throw "Field 'One' must be fully assigned before control is returned to the caller", so you have to set One = Two = Three = Four = 0; as well. - manixrock
(2) This has its uses, mostly with binary data. I use a "Pixel" struct with an int32 @ 0, and four bytes for the four components @ 0, 1, 2, and 3. Great for manipulating image data quickly and easily. - snarf
(57) Warning: This approach does not take into account endianness. That means your C# code will not run the same way on all machines. On little-endian CPUs (which store the least significant byte first), the behavior shown will be used. But on big-endian CPUs, the bytes will come out reversed from what you expected. Beware how you use this in production code - your code may not be portable to certain mobile devices and other hardware, and may break in non-obvious ways (eg two files ostensibly in the same format but actually with byte order reversed). - Ray Burns
This approach is not uniform, for example if you try to repeat the same trick with fields of array type, i.e interpret uint[] as int[] - result shall be unverifyable. - desco
@desco, I imagine this could only possibly apply to value types, and not reference types (arrays are reference types). - AviD
18
[+175] [2008-08-18 01:45:02] Mark Cidade

Using @ for variable names that are keywords.

var @object = new object();
var @string = "";
var @if = IpsoFacto(); 

(38) Why would you want to use a keyword as a variable name? Seems to me that this would make code less readable and obfuscated. - Jon
(41) Well, the reason that it's there is that CLI requires it for interoperability with other languages that might use C# keywords as member names - Mark Cidade
marxidad's reason is good. After that, Carl is right. If I had to maintain code where somebody did this, I can't be held responsible for what happens the next time I see them! :) - Matt Blaine
(69) If you ever wanted to use the asp.net MVC HTML helpers and define a HTML class you will be happy to know that you can use @class so it won't be recognised as the class keyword - Boris Callens
(31) Great for extension methods. public static void DoSomething(this Bar @this, string foo) { ... } - Jonathan C Dickinson
(3) This is not a feature, @ is just allowed symbol for naming like _ and many others (name '@this' will not be equal to name 'this') - zihotki
(1) There is a P/Invoke importer that does that if the signatures use C# keywords as parameter names. Looks strange, but makes the import more or less literal. - OregonGhost
(45) @zihotki: Wrong. var a = 5; Console.WriteLine(@a); Prints 5 - SLaks
(1) This especially useful for generated code, where you can influence the attr-names manually. The @attr approach is already used by some XSD-import functionalities for C#/.NET. - Juve
(1) It can also be used to signify that some variable is used as a SqlParameter, var @pMyParameter = 1; new SqlParameter("@pMyParameter",@pMyParameter); - John Leidegren
(15) Personally, i think Class @class is better than Class clazz - Rob Fonseca-Ensor
(13) I often use @return for the return variable, @default for a default value, @this for the first parameter of an extension method, etc. When I use them like this I think it really helps the clarity of the code - especially for extension methods. - Enigmativity
(1) I have a class which has field named "from" and i didn't think that this name can cause a problem but it cause in linq statement because from keyword is belongs to linq statements. Now i learned how to deal with it. - Freshblood
This is also useful in applications where "Events" are a type of business objects (for example planning tools). Being able to name the business object @Event instead of inventing a synonym is really nice. Especially if event is the word used in the "real world": instead of trying to remember what I mean by "happening", I can just call things by their names, regardless of what words the language has reserved. - Tomas Aschan
Event is a valid identifier without an @. But you do need an @ for @event. - Mark Cidade
When dealing with xsd auto-generated xml-based classes, escaping the element name is sometimes a must. for instance: <event /> = @event - cwharris
Could also be handy if a new brew of C# come up with a new keyword that happens to be widely used in your existing code :) - Sylvain Rodrigue
C# isn't likely to ever have any new reserved keywords and any new context-dependent keywords are likely to be overridden by existing code, like with var which will only be used to automatically infer the type if a type named var doesn't exist. - Mark Cidade
Don't forget :: can be used for using aliases where a class name and an alias conflict. I.e. using xyz=System.Windows.Forms; xyz::Form (as opposed to xyz.Form). - BrainSlugs83
The @ sigil is to mitigate conflicts between languages. The :: operator is used to differentiate identical names for classes from different assemblies. - Mark Cidade
19
[+167] [2008-10-13 22:25:51] Jan Bannister

If you want to exit your program without calling any finally blocks or finalizers use FailFast [1]:

Environment.FailFast()
[1] http://msdn.microsoft.com/en-us/library/ms131100.aspx

(12) Note that this method also creates a memory dump and writes a message to the Windows error log. - RickNZ
(1) It should be noted no finalizers or app domain unload events will be called when this method is used... - AwkwardCoder
(1) +1 for the hint, but this is not C#, it is BCL of .NET. - Abel
System.Diagnostics.Process.GetCurrentProcess().Kill() is faster - Tolgahan Albayrak
20
[+153] [2008-08-17 01:01:28] denis phillips

Returning anonymous types from a method and accessing members without reflection.

// Useful? probably not.
private void foo()
{
    var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) });
    Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges);
}

object GetUserTuple()
{
    return new { Name = "dp", Badges = 5 };
}    

// Using the magic of Type Inference...
static T AnonCast<T>(object obj, T t)
{
   return (T) obj;
}

(42) That really doesn't get you anything. It is actually dangerous. What if GetUserTuple is modified to return multiple types? The cast will fail at run time. One of the great things about C#/.Net is the compile time checking. It would be much better to just create a new type. - Jason Jackson
(9) @Jason I did say it's probably not useful but it is surprising (and I thought hidden). - denis phillips
(31) While cool, this seems like a rather poor design choice. You've basically defined the anonymous type in two places. At that point, just declare a real struct and use it directly. - Paul Alexander
I could see this being useful if you have some sort of convention running throughout your application when you return tuples - George Mauer
(6) @George: such a convention would be called a... struct? - R. Martinho Fernandes
(1) I think any potential use there may have been for this has probably been replaced by the dynamic keyword. If you're going to play with fire, you might was well do it the easy way. ;-) - StriplingWarrior
(2) this trick is named 'cast by sample' and it will not work if method that returns anonymous type is located in another assembly. - desco
@desco: "hidden features" not necessarily useful. - denis phillips
@StriplingWarrior: Actually, anonymous types and dynamic go together quite well, so you cannot really say one replaces the other - if that is what you were suggesting. (i.e. with dynamic you could get rid of the cast entirely and just do dynamic user = GetUserTuple(); and the rest would stay the same...) - kloffy
@kloffy: yes, that's exactly what I mean. dynamic doesn't replace anonymous types: it replaces the need for this AnonCast method in order to access members without reflection. - StriplingWarrior
(1) @StriplingWarrior: My bad, I misinterpreted your comment. I absolutely agree that the dynamic version is to be preferred (maybe it should be added to this answer as an alternative)... - kloffy
weird. My co-worker and I actually wrote this exact function at a former job.... we had a (semi-)legitimate use case for it, but ended up just making a new type and removing the function before someone used it for evil ;) - John Gibb
21
[+146] [2008-08-12 18:38:16] Patrick

Here's a useful one for regular expressions and file paths:

"c:\\program files\\oldway"
@"c:\program file\newway"

The @ tells the compiler to ignore any escape characters in a string.


(27) Also, a @ constant accepts newlines inside. Perfect when assigning a multiline script to a string. - Tor Haugen
(11) Don't forget also to escape a quotation mark just double them up, in other words. [code]var candy = @"I like ""red"" candy canes.";[/code] - David
(5) I tend to build paths with Path.Combine. I definitely use the @ for regex! - Dan McClain
(6) @new is also a variable instead of a keyword: @this, @int, @return, @interface...so on :) - IAbstract
This one doesn't come anywhere near: But what are the most hidden features or tricks of C# that even C# fans, addicts, experts barely know? - publicgk
22
[+141] [2008-10-26 19:04:33] Dmitri Nesteruk

Mixins. Basically, if you want to add a feature to several classes, but cannot use one base class for all of them, get each class to implement an interface (with no members). Then, write an extension method for the interface, i.e.

public static DeepCopy(this IPrototype p) { ... }

Of course, some clarity is sacrificed. But it works!


(4) Yeah I think this is the real power of extension methods. They basically allow for implementations of interface methods. - John B
This is also handy if you're using NHibernate (or Castle ActiveRecord) and you have to use interfaces for your collections. This way you can give behavior to the collection interfaces. - Ryan Lundy
That's basically how all of the LINQ methods are implemented, for the record. - Isabelle Wedin
Here's a link that talks about what I referred to above, using extension methods with collection interfaces in NHibernate or Castle ActiveRecord: devlicio.us/blogs/billy_mccafferty/archive/2008/09/03/… - Ryan Lundy
(7) If only they allowed extension properties!!!! I hated having to write an extension method that begged to be a read-only property.... - John Gibb
It's not strictly a mixin unless you can decorate a class with an interface after the fact - but still cool :) - MattDavey
23
[+130] [2008-08-12 18:53:44] Michael Stum

Not sure why anyone would ever want to use Nullable<bool> though. :-)

True, False, FileNotFound [1]?

[1] http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx

(87) if expect a user to answer a yes no question then null would be appropriate if the question has not been answered - Omar Kooheji
(2) I used a nullable bool when populating a ddl of employees. Active only = true. InActive only - false. Active and Inactive = null - DiningPhilanderer
Omar is on the right track--imagine a web form with two radio buttons "Yes" and "No" but no default selection. If the user submits the form without clicking either button, you have a null choice. Also could be useful for something like "Did we succeed, fail, are we still waiting for the result?" - John Zwinck
I actually use that in a similar fashion in a class that serves as a filter. You can set a bool? to true/false, or just leave it as null to say "Don't filter by that column". But still, someone HAD to bring up the FileNotFound one, especially after someone else laid the groundwork already. - Michael Stum
(22) Nullable types are handy for interaction with a database where table columns are often nullable. - tuinstoel
(11) Yes, No, Maybee? - Dan Blair
(21) Store values of a ThreeState CheckBox - Shimmy Weitzhandler
(8) As in SQL: Yes/no/unknown. - erikkallen
(3) Using enum is a better approach instead of using nullable boolean - JCasso
(1) Usually yes, especially as enums are speaking for themselves. However, enums are yet another type, and adding new types is not always a good idea. As usual, it depends. - Michael Stum
One day i was thinking about this and meanwhile our company announced a new Health Insurance scheme and Forms where given to all employee to fill and in the bottom of the form i saw a Question "Are You pregnant?" and Options were "Yes" OR "NO" i was shocked to find out how a male can respond to this. So I made a New Option Box in Form with Title NA(Not Applicable) and marked that one. From that day i realize why we need Nullable<bool> :). And I my view while development there are many times you code paths never answers against your boolean flag and that is the exact place you need bool? - Mubashar
Utterly diffident, one fails to answer Yes and No question with a Maybe. - devXen
@erikkallen you mean 1 / 0 / NULL, a Nullable bool field. - Shimmy Weitzhandler
Nullable<bool> doesn't make sence to me either, as a boolean is "Yes/No", there is no maybe... - stoic
@Dusty There are some examples in the comments. NULL usually means "I don't know" or "Not set/No Decision has been made". Think of creating a database filter where you want to allow the user to show only items where a bool is TRUE, FALSE or both/ignore the filter. - Michael Stum
@Mubashar null is not maybe, not applicable or similar it by definition means "no information" as in I don't know what the value mean since it has no meaning. Modeling three state checkboxes and other three state with bool? should rather be implemented as enum or other three state representation - Rune FS
@Dan Blair: I don't know, could you repeat the question? - efdee
There are lots of uses for trinary logic. Yes|No|Undefined, Yes|No|No-Response, Yes|No|N/A, etc. Really anything that has 3 possible states. - Justin Morgan
True, False, not yet set - Larry
SQL is the main reason. Also nice as a trycast: var a = expr as bool?; if (a != null){ // do something with a.value} else { // expr wasn't a bool } - John Gibb
@Dan Blair: In portuguese the Word for Yes is Sim, the word for No is Não. In recent political speeches, it was invented a new word: "Nim". A mixture of Yes and No! - sergiol
(1) The reason to use a Nullable< bool > is to accurately answer questions like, "Have you stopped beating your wife?". Yes, No or N/A - Dan
For some of you commenters, I'd suggest not thinking of null as just another value. Null should be restricted to situations where it means "don't know", "don't care", or "not applicable". Ideally, we wouldn't even use it for the "no value" case, but that is hard to avoid. Once you have this in mind, it is easy to think of scenarios that you would want a bool?. All that being said, most often using a reasonable default value is better than relying on null references. - Patrick Szalapski
24
[+116] [2008-08-16 23:55:28] Brad Wilson

This one is not "hidden" so much as it is misnamed.

A lot of attention is paid to the algorithms "map", "reduce", and "filter". What most people don't realize is that .NET 3.5 added all three of these algorithms, but it gave them very SQL-ish names, based on the fact that they're part of LINQ.

"map" => Select
Transforms data from one form into another

"reduce" => Aggregate
Aggregates values into a single result

"filter" => Where
Filters data based on a criteria

The ability to use LINQ to do inline work on collections that used to take iteration and conditionals can be incredibly valuable. It's worth learning how all the LINQ extension methods can help make your code much more compact and maintainable.


Select force you to always return something from the supplied expression wherears map is less picky about that. - chakrit
(1) Select also acts like the "return" function in monads. See stackoverflow.com/questions/9033/hidden-features-of-c#405088 - Mark Cidade
(1) Using "select" is only required if you use the SQLish syntax. If you use the extension method syntax -- someCollection.Where(item => item.Price > 5.99M) -- the use of select statements isn't required. - Brad Wilson
(7) @Brad, that (where) is a filter operation. Try doing a map operation without select... - Eloff
(2) LINQ is the big thing that happened to C# in my opinion: stackoverflow.com/questions/2398818/… - Leniel Maccaferri
(1) Aggregate's smallest signature is the "reduce" function, Aggregate's middle signature is the much more powerful "fold" function! - Brett Widmeier
Select is very powerful, for examples such as: string[] fileNames = a_directoryInfo.GetFiles().Select(fileInfo => fileInfo.Name).ToArray(); - Chuck Savage
This drives me nuts. I always go through the same process: "I need to do a map, let's see that would be... wait... wait... select!" - Ferruccio
25
[+115] [2008-09-01 00:03:41] nimish
Environment.NewLine

for system independent newlines.


(10) The annoying thing about this one, is that it isn't included into the compact framework. - Stormenet
(14) Its worth pointing out that this is specific to the application's host platform - so if you are creating data intended for another system, you should use \n or \r\n appropriately. - Mesh
This is part of the BCL of .NET, not a feature of C# per se. - Abel
26
[+111] [2008-08-18 22:29:45] Portman

If you're trying to use curly brackets inside a String.Format expression...

int foo = 3;
string bar = "blind mice";
String.Format("{{I am in brackets!}} {0} {1}", foo, bar);
//Outputs "{I am in brackets!} 3 blind mice"

(19) @Kyralessa: Actually, yes, they are braces, but "curly brackets" is an alternate name for them. [ and ] are square brackets, and < and > are angle brackets. See en.wikipedia.org/wiki/Bracket. - icktoofay
(4) You are correct. But when I commented, it didn't say "curly" brackets. - Ryan Lundy
(2) Very nice one to point out. Remember my first String.Format looked like: String.Format("{0}I am in curly brackets{1} {2} {3}", "{","}", 3, "blind mice"); Once I found out that escaping these is done by using {{ and }} I was so happy :) - Gertjan
Muahahahaa... Programming already 3 years in .Net and I didn't know this one. :D - Arnis Lapsa
"curly" brackets acting similar to escape sequences ?? - Pratik
@Kyralessa, @icktoofay: we should try to stop being programmers in conversation :) See jwz vs. Branden - sehe
27
[+104] [2008-08-12 16:35:55] kokos
  1. ?? [1] - coalescing operator
  2. using ( statement [2] / directive [3]) - great keyword that can be used for more than just calling Dispose
  3. readonly [4] - should be used more
  4. netmodules - too bad there's no support in Visual Studio
[1] http://msdn.microsoft.com/en-us/library/ms173224.aspx
[2] http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx
[3] http://msdn.microsoft.com/en-us/library/sf0df423(VS.71).aspx
[4] http://msdn.microsoft.com/en-us/library/acdd6hb7(VS.100).aspx

"using - great keyword that can be used for more than just calling Dispose" I am intrigued, can you elaborate on that? - HitLikeAHammer
(6) using can also be used to alias a long namespace to a more convenient string, i.e.: using ZipEncode = MyCompany.UtilityCode.Compression.Zip.Encoding; There's more here: msdn.microsoft.com/en-us/library/sf0df423.aspx - Dave R.
(2) It really isn't the same thing. When calling Dispose, you may use the using statement, when aliasing types you are using a using directive. - Øyvind Skaar
The using block has the syntax using(expr)block which means, that you don't have to store the IDisposable resource in a local variable. You can abuse this feature to enforce arbitrary methods to be called at the end of the block: using(Writer.Indent()) Writer.WriteLine("x"); - Christian Klauser
(2) Just in case you'd like a name to #1 (as you did with the ternary operator), ?? is called the null coalescing operator. - J. Steen
Definitely with you on #4. I have started using netmodules for test demos of code that I keep in one big DEV project, and then want to incorporate them in my proof-of-concept project without having 100 different dlls for all those bits. - maxwellb
(4) @LucasAardvark: As J Steen mentioned it's called the null coalescing operator. Search for that! - kokos
(1) To search for ?? operator at google try: google.com/search?q=c%23+%3F%3F+operator - backslash17
28
[+103] [2008-08-12 18:03:12] Dogmang

@Ed, I'm a bit reticent about posting this as it's little more than nitpicking. However, I would point out that in your code sample:

MyClass c;
  if (obj is MyClass)
    c = obj as MyClass

If you're going to use 'is', why follow it up with a safe cast using 'as'? If you've ascertained that obj is indeed MyClass, a bog-standard cast:

c = (MyClass)obj

...is never going to fail.

Similarly, you could just say:

MyClass c = obj as MyClass;
if(c != null)
{
   ...
}

I don't know enough about .NET's innards to be sure, but my instincts tell me that this would cut a maximum of two type casts operations down to a maximum of one. It's hardly likely to break the processing bank either way; personally, I think the latter form looks cleaner too.


You know - believe it or not - the direct cast is slower than the as cast. I didn't believe this until I measured it myself. - Kent Boogaart
(16) If the cast is to the exact type (cast to "A" when object is "A", not derived from it), the straight cast is ~3x FASTER than "as". When casting a derived type (cast to "A" when object is "B", which derives from "A"), the straight cast is ~0.1x slower than "as". "is", then "as" is just silly. - P Daddy
FxCop will warn you if you place a 'as' inside an 'if is'. - Jonathan C Dickinson
not knowing C#, but borrowing from c++, does this work? if(MyClass c = obj as MyClass) { ... } - Will
Will: That won't work in c#, because null and false cannot be compared to each other. - Neil
(2) No, but you could write "if ((c = obj as MyClass) != null)". - Dave Van den Eynde
@P Daddy: as Kent said, as casting is faster anyway. I've also benchmarked this and found this to be the case. - Ben Collins
(10) is and as won't do user casts. So, the above code is asking with the is operator if obj is derived from MyClass (or has an implicit system defined cast). Also, is fails on null. Both of these edge cases may be important to your code. For instance, you may want to write: if( obj == null || obj is MyClass ) c = (MyClass)obj; But this is strictly different from: try { c = (MyClass)obj; } catch { } since the former will not perform any user defined conversions, but the latter will. Without the null check, the former will also not set c when obj is null. - Adam Luter
@Adam Just wanted to point something out. In your first example, if( obj == null || obj is MyClass ) c = (MyClass)obj; you might as well just use as, since it's clearer, has slightly better performance characteristics, and (if I'm reading it correctly) performs the same work. I believe it's FxCop that points out that is performs an as-like cast under the covers, and it flags that double-cast–style as bad practice. - Isabelle Wedin
It seems to me to just try to use it as what you expect it to be, wrap it in a try/catch and then handle the error appropriately if it occurs. As in an override Equals(object arg){ try{ return ((MyClass)arg).Id == this.Id; } catch{ return base.Equals(arg); }} - Chuck Savage
(2) In IL, a cast goes to a CASTCLASS but an as/is go to an ISINST instruction. - John Gibb
(5) I ran a test for this, casting IEnumerable<int> to List<int>, and casting object (new object()) to IEnumerable<int>, to make sure there are no mistakes: direct cast: 5.43ns, is->as cast: 6.75ns, as cast: 5.69ns. Then testing invalid casts: direct cast: 3125000ns, as cast: 5.41ns. Conclusion: stop worrying about the 1% factor, and just make sure you use is/as when the cast might be invalid, cause exceptions (also if handled) are VERY slow compared to casting, we're talking about a factor 578000 slower. Remember that last part, the rest doesn't matter (.Net FW 4.0, release build) - Aidiakapi
29
[+98] [2008-08-19 15:54:52] JasonS

Maybe not an advanced technique, but one I see all the time that drives me crazy:

if (x == 1)
{
   x = 2;
}
else
{
   x = 3;
}

can be condensed to:

x = (x==1) ? 2 : 3;

If I'm not mistaken, this has been around since some of the early days of C++. (Straight C probably had it too but I can't recall.) - lc.
"This" is called the "ternary operator". en.wikipedia.org/wiki/Ternary_operation - Portman
(10) The ternary operator has been banned in my group. Some people just don't like it, though I've never understood why. - Justin R.
(13) I guess because they're not the same things, being an operator not a statement. I prefer the first approach myself. It's more consistent and easily expandable. Operators can't contain statements, so the minute you have to expand the body, you'll have to convert that ternary operator to an if statement - kervin
(16) can be condensed to x++; Ok it's pointless ^^ - François
(5) @Guillaume: To account for all values of x: x = 2 + System.Math.Min(1,System.Math.Abs(x-1)); - mbeckish
(38) It's actually called the "conditional operator" - it is a ternary operator because it takes three arguments. en.wikipedia.org/wiki/Conditional_operator - Blorgbeard
(1) @kervin: conditional operator can contain statements, if its 2nd and 3rd parts both have the same type. E.g.: (t == null) ? "Null" : t.GetType().Name contains statement in the 3rd part. - Roman Boiko
But it can't be used if statement is required, because conditional operator is just an expression with some value, and not a statement. See also: stackoverflow.com/questions/1816859/… - Roman Boiko
@Roman those aren't statements, just expressions. - siride
@siride Thanks. There are multiple definitions of statements vs expressions which got me confused. Some useful explanations: msdn.microsoft.com/en-us/library/ms173143.aspx (switch to C# tab), and stackoverflow.com/questions/19132/expression-versus-statemen‌​t/… - Roman Boiko
x = x == 1 ? ((Func<int>)(() => { Console.Write("This is a statement"); return 2; })).Invoke() : 3; - Martin Booth
string s = x==1? "one" : x==2? "two" : x==3? "three" : "zero"; - Broken_Window
@Martin cool, but I have to say its difficult to read - Mel
@Mel I agree, I have heard its the death penalty in most countries for anyone who does it too - Martin Booth
I use the ternary operator when needed, and hate it every time. It is so ugly and destroys readability. An expanded if/then statement is so much nicer to read. - Jeremy
(2) @François: No, this isn't the same as x++... Don't assume x is either 1, 2 or 3... it can be anything. - Jeroen Landheer
30
[+94] [2009-04-15 00:23:53] Ralph Caraveo

Many people don't realize that they can compare strings using: OrdinalIgnoreCase instead of having to do someString.ToUpper(). This removes the additional string allocation overhead.

if( myString.ToUpper() == theirString.ToUpper() ){ ... }

becomes

if( myString.Equals( theirString, StringComparison.OrdinalIgnoreCase ) ){ ... }

(39) This could be changed quite easily to be null-safe as well: var isEqual = String.Equals(a, b, StringComparison.OrdinalIgnoreCase); - Robert Giesecke
But... this isn't a C# feature, it is a feature of the .Net framework, more specifically a feature of the class "String" - Jeroen Landheer
31
[+79] [2008-10-17 16:41:51] Cristian Libardo

Just learned, anonymous types can infer property names from the variable name:

string hello = "world";
var o = new { hello };
Console.WriteLine(o.hello);

this is because anonymous types are not anonymous after compilation. - dipak
32
[+75] [2008-08-12 16:38:50] Nick Berardi

Honestly the experts by the very definition should know this stuff. But to answer your question: Built-In Types Table (C# Reference) [1]

The compiler flagging for numbers are widely known for these:

Decimal = M
Float = F
Double = D

// for example
double d = 30D;

However these are more obscure:

Long = L
Unsigned Long = UL
Unsigned Int = U
[1] http://msdn.microsoft.com/en-us/library/ya5y69ds.aspx

(4) Every time I'm dealing with decimals, I have to look up the m. Is it only me or is m not really intuitive? :) - OregonGhost
(47) The M syntax comes from the old VB type called Money. M == Money == Decimal. - Nick Berardi
(3) Nope, anything less than an Int32 is automatically inferred by the compiler based on the type to the left of it - Nick Berardi
(2) @Nick: nice - I like learning the historicals behind the code. - IAbstract
@OregonGhost : and I guess the D was already taken :) - MBen
@Nick, Thanks for the history of m for decimal, this will help me remember this one. The one I never use is D for double; I always prefer writing 30.0 and curiously I regularly use the L for long. - odalet
It's interesting to note that though the lower case variants are valid, using l for long is discouraged because it can be easily mistaken for 1. - odalet
(1) I remember M=Decimal/D=Double the same way I remember port/starboard: starboard means "Right" and has more "R"s. Decimal has an M but Double does not. - goldenratio
33
[+75] [2008-08-28 20:59:59] ljs

I like looking up stuff in a list like:-

bool basketContainsFruit(string fruit) {
  return new[] { "apple", "orange", "banana", "pear" }.Contains(fruit);
}

Rather than:-

bool basketContainsFruit(string fruit) {
  return fruit == "apple" || fruit == "orange" || fruit == "banana" ||
    fruit == "pear";
}

Doesn't come up that much in practice, but the idea of matching items against the subject of the search can be really quite useful + succinct.


I'm curious what the compiler spits out for both implementations. The first one definitely looks cleaner and is a cute way of doing it. Could be slower though if the object is actually created in memory first then iterated through. - lc.
you probably wanted fruit == banana? - el2iot2
Kinda cool. But I would tweak it to use a static array so that it's not being newed every time the method is called. - xanadont
Used InList in Visual Foxpro. Created lame static method which accepts params list just to reproduce the same. I'm glad there is a cleaner approach. :) - Arnis Lapsa
You know that the first method every call a new array is created and that calling Contains is lots of slower than a few comparisons. But yes, it is convenient :) - codymanix
@codymanix 0 yes, it's inefficient, but most of the time the inefficiency makes no difference to the perf of the application. Don't optimise unless the profiler says so :) - prefer readability over micro-perf issues unless the profiler disagrees :) - ljs
(7) But you can have the best of both worlds (at least for this example, or for any integral type) using switch. Example follows, but readability suffers in comments due to lack of newlines: switch(fruit){ case "apple": case "orange": case "banana": case "pear": return true; default: return false; } - P Daddy
except that in c# we don't have fallthrough - Fowl
(2) @P Daddy - true, but does suffer from a lot of additional syntax. @Fowl - you can have fallthrough if the cases have no code (until the fallen-through case of course). - ljs
@Fowl, yes we have, only for empty case statements, like this. - Michael
(3) public static bool In<T>(T value, params T[] items){ return items.Contains(value); } if (fruit.In("apple", "orange", "banana", "pear")) { ... } - John Gibb
This code creates new array each call. Actually it is incorrect when you create an new object when you really need to verify an argument. And please, dont tell me about readability. Semantically wrong syntax can not be readable. And short code/nicely put braces is not readability. - Grigory
(1) @Belorus I think you're treating it as if readability were a science, which it is not. Yes, it is a performance hit, but very often it will make no difference to the overall performance of the program. How is it 'wrong' if it does the job, even if it needlessly allocates memory? Readability is a very subjective thing - what seems simple to one person can seem appalling to another. - ljs
For me this is a classic example of bad programming. Terrible performance, bad readability. (Yes, second statement is subjective.) - Jan Slodicka
34
[+73] [2008-09-05 16:10:21] DAC

InternalsVisibleTo [1] attribute is one that is not that well known, but can come in increadibly handy in certain circumstances. It basically allows another assembly to be able to access "internal" elements of the defining assembly.

[1] http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

(12) I use this regularly for writing unit tests against internal members of another assembly. That way unit tests can be excluded from deployments. - Drew Noakes
This is definitely my best discovery from this topic. The best solution I had found on my own to give unit tests in a different assembly access to internal methods was to make the methods protected and write pseudo-mock classes in my test assembly that inherited from the class being tested. - Mark Nelson
InternalsVisibleTo is very useful for exposing a protected internal parameterless .ctor to a NHibernate layer whilst hiding it from a user application which can then only use the public .ctor that enforces supplying required data. - Scott Rickman
35
[+72] [2010-06-22 03:59:04] jcruz

Here is a new method of the string class in C# 4.0:

String.IsNullOrWhiteSpace(String value)

It's about time.


(3) What's the problem with making your own util method that returns this: (myString ?? "").Trim() == "" - user47322
(1) @Charlie Isn't a carriage return treated as whitespace too? - MPritchard
(4) I definitely prefer Haack's approach now that I have tried it out. You put together string extensions methods for AsNullIfEmpty and AsNullIfWhiteSpace. By doing it this way, you can then use the result in a coalescing operator: SomeString.AsNullIfEmpty() ?? "default value". - patridge
I forgot that I had to tweak Haack's code to do something like @Charlie has because he uses the new IsNullOrWhiteSpace. I still like being able to consume the result in a ?? operator, though. - patridge
(2) I really don't like "". You should use string.Empty (myString ?? string.Empty).Trim() == string.Empty as it conveys a bit more. - Dan
(3) On the record, I absolutely HATE string.Empty. What could it ever be besides ""? The performance benefit of a static field vs an interned string will be negligible: stackoverflow.com/questions/263191/… - John Gibb
36
[+70] [2008-10-06 15:30:27] t4

I picked this one up when using ReSharper [1]:

Implicit Method Group Conversion

//If given this:
var myStrings = new List<string>(){"abc","def","xyz"};
//Then this:
myStrings.ForEach(s => Console.WriteLine(s));
//Is equivalent to this:
myStrings.ForEach(Console.WriteLine);

See " Implicit Method Group Conversion in C# [2]" for more.

[1] http://www.jetbrains.com/resharper/
[2] http://blog.opennetcf.com/ncowburn/2007/03/23/ImplicitMethodGroupConversionInC.aspx

not for Debug.WriteLine though cuz it uses a #if DEBUG statement internally. - Henrik
@AndyC: It's not about that here (ForEach is simply defined as a custom extension method somewhere. There are religious debates over that elsewhere :)) - sehe
IMHO, the following looks better ----------------- foreach(string s in myString) Console.WriteLine(s); - Grigory
37
[+68] [2008-08-12 16:45:22] JamesSugrue
  • TransactionScope and DependentTransaction [1] in System.Transactions is a lightweight way to use transaction processing in .NET - it's not just for Database transactions either [2]
  • String.IsNullOrEmpty is one that I am surprised to learn a lot of developers don't know about
  • List.ForEach - iterate through your generic list using a delegate method

There are more, but that is the three obvious ones of the top of my head...

[1] http://msdn.microsoft.com/en-us/library/system.transactions.dependenttransaction.aspx
[2] http://msdn.microsoft.com/en-us/library/ms229973.aspx

I found that TransactionScope aggressively promotes transactions to distributed mode which uses DTC. When DTC becomes involved you'll probably have to deal with DCOM security. I tend to avoid the pain by using native transactions. - Hans Malherbe
(17) That List.ForEach is faster than foreach or for(;;) is completely bonkers. ForEach uses a method/function delegate to implement the behavior. This is first of all, means worse cache locality because the code is generally executed further away (in memory) from the actual loop. Secondly all you really need to do to verify that this is slower is to look a the generated native code. There's a lot more stuff going on with List.ForEach than you might think. - John Leidegren
Completely bonkers? Well, I found .ForEach to be faster than all other options. See jerrytech.blogspot.com/2010/02/… if you doubt me. Always doubt me ;) The code's there - run it yourself and see. - Jerry Nixon
On the other hand, Patrick Smacchia says the opposite: ForEach is slower than For. codebetter.com/blogs/patricksmacchia/archive/2008/11/19/… - James
(7) There's now also String.IsNullOrWhitespace - Ray
One caveat - note that TransactionScope's default Isolation is ReadSerializable (whereas the usual default is just Read Committed). This can cause a lot of deadlocks unless you override your TS. See blogs.msdn.com/b/dbrowne/archive/2010/05/21/… - StuartLC
@JerryNixon Your test is completely bonkers. And the timing results you posted don't even fit the code you provided. - CodesInChaos
@JerryNixon Your graphs look about right for that code but I don't think you are testing what you want to be testing. Either go with: using (var junk = m_Source.GetEnumerator()) for (; junk.MoveNext();) _Target1.Add(junk.Current + 1); or for (int i = 0; i < m_Source.Count; i++) // Count property - Dandy
38
[+68] [2010-06-22 19:22:03] Steve Dunn

When debugging, you can type $exception in the Watch\QuickWatch\Immediate window and get all the info on the exception of the current frame. This is very useful if you've got 1st chance exceptions turned on!


39
[+66] [2008-09-19 20:02:05] Wyzfen

Dictionary.TryGetValue(K key, out V value)

Works as a check and a get in one. Rather than;

if(dictionary.ContainsKey(key)) 
{
    value = dictionary[key];
    ...
}

you can just do;

if(dictionary.TryGetValue(key, out value)) 
{ ... }

and the value has been set.


(19) Another benefit of TryGetValue is that if your dictionary is synchronized, there is no race condition. Compared to ContainsKey where another thread could remove the item you are looking for between calls. - Guvante
(4) TryGetValue throws if the key is null -- so much for avoiding axceptions. I use a TryGetValue2() extension method to get around this problem. - Qwertie
(3) Looking up a null in a dictionary seems more likely a code error than looking up a non-existent value. I personally am glad that it throws the exception ;) - John Gibb
40
[+65] [2009-08-05 05:57:55] Christian Hubmann

Conditional string.Format [1]:

Applies different formatting to a number depending on whether the number is positive, negative, or zero.

string s = string.Format("{0:positive;negative;zero}", i);

e.g.

string format = "000;-#;(0)";

string pos = 1.ToString(format);     // 001
string neg = (-1).ToString(format);  // -1
string zer = 0.ToString(format);     // (0)
[1] http://msdn.microsoft.com/en-us/library/0c899ak8.aspx#SectionSeparator

(2) This is similar to reg expressions, very useful, but I can't remember them either. I handle stuff like above with padleft and padright. - tuinstoel
Cool, I never knew it was possible... Is it documented anywhere ? - Thomas Levesque
@Thomas: It's documented in MSDN in the "The ";" Section Separator" section towards the end of the Custom Numeric Formatting topic at: msdn.microsoft.com/en-us/library/0c899ak8.aspx - devstuff
41
[+64] [2008-08-18 07:33:17] Mark Cidade

Events are really delegates under the hood and any delegate object can have multiple functions attached to it and detatched from it using the += and -= operators, respectively.

Events can also be controlled with the add/remove, similar to get/set except they're invoked when += and -= are used:

public event EventHandler SelectiveEvent(object sender, EventArgs args) 
  { add 
     { if (value.Target == null) throw new Exception("No static handlers!");
       _SelectiveEvent += value;
     }
    remove
     { _SelectiveEvent -= value;
     }
  } EventHandler _SelectiveEvent;

42
[+61] [2008-09-18 02:33:51] John Spurlock

Don't forget about goto [1].

[1] http://msdn.microsoft.com/en-us/library/13940fs2(VS.71).aspx

(55) No, lets forget it. ;) - Gary Willoughby
(3) No, lets abuse it till kingdom come. ;) - chakrit
(1) Yeah, don't forget it--make sure to nuke it when you have a chance! - Loren Pechtel
from the old days of AppleSoft basic: gosub/return ;) - IAbstract
I once had a co-worker that claimed that he had found a legitimate use of goto, that is as use that made function clearer that with other alternatives. I looked at the code and asked some questions how it worked. When I asked him at the coffe break one hour later he had changed to a break (I think). At least goto is very general and easy to implement in a compiler. - user376591
#region hidden / goto haiku_secretly / #endregion // hidden - sehe
(11) +1. How do you break out from multiple levels of loops without messing with bool variables or moving the entire thing to a function or lambda? There should be a reason why does it exist in the language... - Calmarius
(1) Two or three levels deep in nested loops and this is an absolute godsend. Can't think of any other possible legitimate reason to use it though. - tomfanning
(1) @tomfanning - how about fall-through in switch statements? Goto is perfect for this. - Fraser
@Calmarius I've seen parametrized "break" and "continue" in other languages, like "break 3" to break up to the third for/while/etc. It's also prone to errors, because if you inadvertently add a new inner loop in the code, the "break 3" might break the wrong loop. Goto is a cleaner way to do that, IMHO. A better way to solve this would be to have named loops like "for(....) as myloop { .... }" and then "break myloop", but I didn't see that in any language. - Guillermo Prandi
43
[+56] [2008-10-18 11:54:28] Mike Two

More of a runtime feature, but I recently learned that there are two garbage collectors. The workstation gc and the server gc. Workstation is the default on client versions of windows, but server is much faster on multicore machines.


<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

Be careful. The server gc requires more memory.


Nice tip. You should move this question to the Hidden .NET Base Class Library question stackoverflow.com/questions/122784/… - John Sheehan
Awesome. I've got a multicore webserver; its extra core and memory have been going to waste! - tsilb
This optimization works well for me on IronScheme too :) - leppie
(3) On server SKUs of Windows (Server 2003, etc) the default is to use the server GC. The workstation GC is the default on client SKUs such as Vista. - dso
44
[+55] [2008-09-15 14:58:26] Grokys

I couldn't see this looking above - one that I didn't realise you could do until recently is to call one constructor from another:

class Example
{
    public Example(int value1)
        : this(value1, "Default Value")
    {
    }

    public Example(int value1, string value2)
    {
        m_Value1 = value1;
        m_value2 = value2;
    }

    int m_Value1;
    string m_value2;
}

(1) Although I used this thing cross classes, I never thought of using it in the same class. I have been looking all over the place for something like that! Great! - Boris Callens
That's great. I always used that calling the base, but never knew you could use it in the same class! - lc.
can you guys link to somewhere showing a usage example of this for cross class and base class? - Maslow
Yea, I use this all of the time. It really is handy, and very intuitive I think. - Steven Evers
(3) I think you meant: public Example(int value1) : this(value1, "Default Value") { } - rball
(1) Well spotted rball! 1 year, 21 upvotes and nobody spotted my deliberate mistake ;) Fixed. - Grokys
Thanks to C# 4.0 there's no reason to do something this simple, you can just make the second parameter optional (please excuse the lack of line breaks): public Example(int value1, string value2 = "Default Value") {...} - Corey Ogburn
Also you can use this similar technique when you inherit base classes. Similar usage: ": base(value1, "Default Value")" - J. Mitchell
45
[+55] [2008-12-10 13:11:49] Binoj Antony

Other underused operators are checked and unchecked:

short x = 32767;   // 32767 is the max value for short
short y = 32767;
int z1 =  checked((short)(x + y));   //will throw an OverflowException
int z2 =  unchecked((short)(x + y)); // will return -2
int z3 =  (short)(x + y);            // will return -2

(6) Instead of 32767 and a comment, how about short.MaxValue? - Clinton Pierce
(25) Just reminding everyone what the exact MaxValue is! - Binoj Antony
perhaps we should list '32767' as the max value for a short as a hidden language feature of itself? (I think it is hidden programmer ethics to hardcode the number) - sehe
46
[+55] [2009-06-16 17:14:06] JoshL

Use "throw;" instead of "throw ex;" to preserve stack trace

If re-throwing an exception without adding additional information, use "throw" instead of "throw ex". An empty "throw" statement in a catch block will emit specific IL that re-throws the exception while preserving the original stack trace. "throw ex" loses the stack trace to the original source of the exception.


47
[+48] [2008-09-26 15:28:11] Jon Skeet

A few hidden features I've come across:

  • stackalloc which lets you allocate arrays on the stack
  • Anonymous methods with no explicit parameter list, which are implicitly convertible to any delegate type with non-out/ref parameters (very handy for events, as noted in an earlier comment)
  • A lot of people aren't aware of what events really are (an add/remove pair of methods, like get/set for properties); field-like events in C# really declare both a variable and an event
  • The == and != operators can be overloaded to return types other than bool. Strange but true.
  • The query expression translation in C# 3 is really "simple" in some ways - which means you can get it to do some very odd things [1].
  • Nullable types have special boxing behaviour: a null value gets boxed to a null reference, and you can unbox from null to the nullable type too.
[1] http://msmvps.com/blogs/jon_skeet/archive/2008/02/29/odd-query-expressions.aspx

(1) Unfortunately, stackalloc requires unsafe context. - RickNZ
48
[+48] [2009-11-09 06:58:35] Himadri

I just wanted to copy that code without the comments. So, the trick is to simply press the Alt button, and then highlight the rectangle you like.(e. g. below).

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        //if (e.CommandName == "sel")
        //{
        //    lblCat.Text = e.CommandArgument.ToString();
        //}
    }

In the above code if I want to select :

e.CommandName == "sel"

lblCat.Text = e.Comman

Then I press ALt key and select the rectangle and no need to uncomment the lines.

Check this out.


(2) Interesting Visual Studio feature, but the question is about C#. - Fernando
(11) +1 There is a section "Visual Studio Features" in this question, where your answer fits perfectly. - Roman Boiko
Also it worked just by hit on Alt. Not need to press and hold Alt. - A1exandr Belan
(4) It's not just Visual Studio feature. you can do this in Microsoft Word Notepad2 etc. etc. - chakrit
Very limited compared to Vim's block selection, though. - Don Reba
(13) VS2010 lets you not only select, but edit text in this fashion - such as adding the word "private" to the beginning of every line simply by alt-selecting the space before the lines and starting to type - thereby correcting a poor practice of leaving off the word on multiple field declarations at the same time. - Matt DeKrey
(1) This is called vertical selection in many text editors - Singlet
49
[+46] [2008-09-05 13:54:30] Konamiman

@David in Dakota:

Console.WriteLine( "-".PadRight( 21, '-' ) );

I used to do this, until I discovered that the String class has a constructor that allows you to do the same thing in a cleaner way:

new String('-',22);

Why not do this Console.WriteLine( "".PadRight( 22, '-' ) ); - Jimmy
To achieve shorter and cleaner code, for example. - Konamiman
50
[+46] [2008-09-12 18:24:24] Jakub Šturc

The volatile [1] keyword to tell the compiler that a field can be modified by multiple threads concurrently.

[1] http://msdn.microsoft.com/en-us/library/x13ttww7.aspx

(18) Hey, this is not exactly true. The volatile keyword instructs the compiler to generate an acquire-fence on every read from a field, and a release-fence on every write to the field. An acquire-fence prevents other reads/writes from being moved before the fence; a release-fence prevents other reads/writes from being moved after the fence. Read more here: bit.ly/hycbVI - Anvaka
51
[+45] [2008-09-09 14:04:46] Bryan

A couple of things I like:

-If you create an interface similar to

 public interface SomeObject<T> where T : SomeObject<T>, new()

you force anything that inherits from this interface to contain a parameterless constructor. It is very useful for a couple of things I've run across.

-Using anonymous types to create a useful object on the fly:

var myAwesomeObject = new {Name="Foo", Size=10};

-Finally, many Java developers are familiar with syntax like:

public synchronized void MySynchronizedMethod(){}

However, in C# this is not valid syntax. The workaround is a method attribute:

 [MethodImpl(MethodImplOptions.Synchronized)]
 public void MySynchronizedMethod(){}

(2) These are all good ideas. This site generally prefers one idea per answer so they can be rated individually. I would have given you three ratings :) - Drew Noakes
(7) [MethodImpl(MethodImplOptions.Synchronized)] = lock(this) = bad - Greg Dean
I'm not familiar with "Sychronized" method, can you tell me what they do? - Matt Grande
(9) "you force anything that inherits from this interface to contain a parameterless constructor" Strictly speaking, no you don't - you force any class that implements your interface to prove that it know the name of a class that implements the interface and has a parameterless constructor. That's not the same thing. class A : SomeObject<A> { public A() // required } class B : SomeObject<A> { } // will compile fine, no constructor. - James Hart
@Matt, in this case, synchronised (or the methodimpl attribute) locks on the current object while the method is processing. However, the attribute causes a lock(this) while it does it: and in CLR via C# I recall that this was not a good idea (iirc, it exposed a potential security vulnerability but the book is all the way on the other side of the house, and it's really late). This is why most people will lock on a private object member variable instead of lock(this). - Steven Evers
52
[+45] [2008-10-03 05:34:22] Tim Jarvis

The params keyword, i.e.

public void DoSomething(params string[] theStrings)
{
  foreach(string s in theStrings)
  {
    // Something with the Strings…
  }
}

Called like

DoSomething(“The”, “cat”, “sat”, “on”, “the” ,”mat”);

I used params for forbidding the empty constructor in classes: stackoverflow.com/questions/6273404/… - sergiol
53
[+44] [2008-09-04 21:06:29] andynil

Foreach uses Duck Typing

Paraphrasing, or shamelessly stealing from Krzysztof Cwalinas blog [1] on this. More interesting trivia than anything.

For your object to support foreach, you don't have to implement IEnumerable. I.e. this is not a constraint and it isn't checked by the compiler. What's checked is that

  • Your object provide a public method GetEnumerator that
    • takes no parameters
    • return a type that has two members
      1. a parameterless method MoveNext that returns a boolean
      2. a property Current with a getter that returns an Object

For example,

class Foo
{
    public Bar GetEnumerator() { return new Bar(); }

    public struct Bar
    {
        public bool MoveNext()
        {
            return false;
        }

        public object Current
        {
            get { return null; }
        }
    }
}

// the following complies just fine:
Foo f = new Foo();
foreach (object o in f)
{
    Console.WriteLine("Krzysztof Cwalina's da man!");
}
[1] http://blogs.msdn.com/kcwalina/archive/2007/07/18/DuckNotation.aspx

(4) That's awesome! I didn't knwo that... However, same thing with collection initializers... all you need is an Add(x) method. public class MyList{ public void Add(string s){} }. You can then do var l = new MyList{"a", "b", "c"};... - John Gibb
@JohnGibb: Having only an Add method is not sufficient. From section 7.6.10.3 of the C# spec: "The collection object to which a collection initializer is applied must be of a type that implements System.Collections.IEnumerable or a compile-time error occurs." - Gabe
54
[+42] [2008-09-19 07:48:12] core

Static constructors.

Instances:

public class Example
{
    static Example()
    {
        // Code to execute during type initialization
    }

    public Example()
    {
        // Code to execute during object initialization
    }
}

Static classes:

public static class Example
{
    static Example()
    {
        // Code to execute during type initialization
    }
}

MSDN says [1]:

A static constructor is used to initialize any static data, or to perform a particular action that needs performed once only. It is called automatically before the first instance is created or any static members are referenced.

For example:

public class MyWebService
{
    public static DateTime StartTime;

    static MyWebService()
    {
        MyWebService.StartTime = DateTime.Now;
    }

    public TimeSpan Uptime
    {
        get { return DateTime.Now - MyWebService.StartTime; }
    }
}

But, you could also just as easily have done:

public class MyWebService
{
    public static DateTime StartTime = DateTime.Now;

    public TimeSpan Uptime
    {
        get { return DateTime.Now - MyWebService.StartTime; }
    }
}

So you'll be hard-pressed to find any instance when you actually need to use a static constructor.

MSDN offers useful notes on static constructors:

  • A static constructor does not take access modifiers or have parameters.

  • A static constructor is called automatically to initialize the class before the first instance is created
    or any static members are referenced.

  • A static constructor cannot be called directly.

  • The user has no control on when the static constructor is executed in the program.

  • A typical use of static constructors is when the class is using a log file and the constructor is used to write
    entries to this file.

  • Static constructors are also useful when creating wrapper classes for
    unmanaged code, when the constructor
    can call the LoadLibrary method.

  • If a static constructor throws an exception, the runtime will not
    invoke it a second time, and the type will remain uninitialized for the
    lifetime of the application domain in which your program is running.

The most important note is that if an error occurs in the static constructor, a TypeIntializationException is thrown and you cannot drill down to the offending line of code. Instead, you have to examine the TypeInitializationException's InnerException member, which is the specific cause.

[1] http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx

No need to lock as all the static members are thread safe. - NileshChauhan
Actually there was an internal web service that also could be used to change the value of connectionString too. So the lock was needed, no? I didn't remove the lock because I just copied the code and then added the comment. - core
Okay, I completely removed the example and made everything more clear (I hope!). - core
@nils_gate: No, that's a nasty mistake. You probably think this because MSDN docs often say "static members of SoAndSo class are thread safe." This is not because they're intrinsically thread safe. Quite the opposite, in fact. Since any thread can access static members without even having to share an object reference, then static members are more likely to find themselves in a race condition, which is why Microsoft has taken the trouble to make most of their static members thread safe. - P Daddy
&quotStatic constructors are also useful when creating wrapper classes for unmanaged code&quot, how about static destructor for unmanaged code? ;) - chapluck
FxCop doesn't like static constructors for performace reasons. K. Scott Allen's blog post throws some light on why: odetocode.com/blogs/scott/archive/2004/09/15/… - Ergwun
55
[+40] [2008-08-28 21:46:35] bdukes

A couple other attributes from the System.Diagnostics [1] namespace are quite helpful.

DebuggerBrowsable [2] will let you hide variables from the debugger window (we use it for all private backing variables of exposed properties). Along with that, DebuggerStepThrough [3] makes the debugger step over that code, very useful for dumb properties (probably should be converted to auto-properties if you can take a dependency to the C# 3.0 compiler). As an example

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string nickName;
public string NickName    {
    [DebuggerStepThrough]
    get { return nickName; }
    [DebuggerStepThrough]
    set { this.nickName = value; }
}
[1] http://msdn.microsoft.com/en-us/library/system.diagnostics.aspx
[2] http://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerbrowsableattribute.aspx
[3] http://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerstepthroughattribute.aspx

(6) Beware! DebuggerStepThrough is very handy, but should only be used on trivial implementations. When you are debugging, methods marked with this attribute are skipped entirely by the debugger as if they aren't there (which hides the implementation details from you as you will single step right past it). Breakpoints inside the method won't ever be triggered. - Jason Williams
(11) Hmm...neat trick but I think I'd take fields being visible in the debugger over having all that cruft in my class - George Mauer
Plus if this causes you to miss even one bug ever, it won't have been worth your time. - BlueRaja - Danny Pflughoeft
the usefulness of [DebuggerBrowsable(DebuggerBrowsableState.Never)] is for long database calls for objects like users that have Invoices, Addresses, Phones, CreditCards, etc that are each calls to fill up via database calls. If anyone of these fails to return in time, the whole state of the object returned is unreadable (in the debugger). - Chuck Savage
56
[+39] [2009-11-10 11:28:19] Shital Shah

C# + CLR:

  1. Thread.MemoryBarrier: Most people wouldn't have used it and there is some inaccurate information on MSDN. But if you know intricacies [1] then you can do nifty lock-free synchronization.

  2. volatile, Thread.VolatileRead, Thread.VolatileWrite: There are very very few people who gets the use of these and even fewer who understands all the risks they avoid and introduce :).

  3. ThreadStatic variables: There was only one situation in past few years I've found that ThreadStatic variables were absolutely god send and indispensable. When you want to do something for entire call chain, for example, they are very useful.

  4. fixed keyword: It's a hidden weapon when you want to make access to elements of large array almost as fast as C++ (by default C# enforces bound checks that slows down things).

  5. default(typeName) keyword can be used outside of generic class as well. It's useful to create empty copy of struct.

  6. One of the handy feature I use is DataRow[columnName].ToString() always returns non-null value. If value in database was NULL, you get empty string.

  7. Use Debugger object to break automatically when you want developer's attention even if s/he hasn't enabled automatic break on exception:


#if DEBUG  
    if (Debugger.IsAttached)  
        Debugger.Break();  
#endif
  1. You can alias complicated ugly looking generic types so you don't have to copy paste them again and again. Also you can make changes to that type in one place. For example,

    using ComplicatedDictionary = Dictionary<int, Dictionary<string, object>>;
    ComplicatedDictionary myDictionary = new ComplicatedDictionary();
[1] http://www.albahari.com/threading/part4.aspx

Sweet, great tips, in the last one you had tag trouble... replace < with &lt; and we will be able to read it :) - Cohen
Now most of this comes down to 'people don't know the mechanics behind threading' IMHO. That may be true, but doesn't come close to 'hidden language features'? Thumbs up for Debugger.Break() - sehe
57
[+38] [2008-12-24 18:10:36] Michael Meadows

Closures

Since anonymous delegates were added to 2.0, we have been able to develop closures. They are rarely used by programmers but provide great benefits such as immediate code reuse. Consider this piece of code:

bool changed = false;

if (model.Prop1 != prop1)
{
    changed = true;
    model.Prop1 = prop1;
}
if (model.Prop2 != prop2)
{
    changed = true;
    model.Prop2 = prop2;
}
// ... etc. 

Note that the if-statements above perform similar pieces of code with the exception of one line of code, i.e. setting different properties. This can be shortened with the following, where the varying line of code is entered as a parameter to an Action object, appropriately named setAndTagChanged:

bool changed = false;
Action<Action> setAndTagChanged = (action) => 
{ 
    changed = true; 
    action(); 
};

if (model.Prop1 != prop1) setAndTagChanged(() => model.Prop1 = prop1);
if (model.Prop2 != prop2) setAndTagChanged(() => model.Prop2 = prop2);

In the second case, the closure allows you to scope the change variable in your lambda, which is a concise way to approach this problem.

An alternate way is to use another unused feature, the "or equal" binary assignment operator. The following code shows how:

private bool conditionalSet(bool condition, Action action)
{
    if (condition) action();
    return condition;
}

// ...

bool changed = false;
changed |= conditionalSet(model.Prop1 == prop1, () => model.Prop1 = prop1);
changed |= conditionalSet(model.Prop2 == prop2, () => model.Prop2 = prop2);

I'm not having any luck getting the 2nd one to compile? is it .net 3.5 only? public int eye { get; set; } private void testClosure() { var i = 0; bool changed = false; Action<Action> setAndTagChanged = (action) => { changed = true; action(); }; setAndTagChanged(eye=1); } - Maslow
Lambdas are only available in C# 3.0 or greater. That means you must have .Net 3.5. - Michael Meadows
Thanks, luckily we've moved up to .net 3.5 thanks to my pushing for it - Maslow
+1 Link to closures question:stackoverflow.com/questions/428617/closures-in-net Article with explanation of compiler generated code blogs.msdn.com/b/abhinaba/archive/2005/10/18/482180.aspx - chapluck
58
[+38] [2009-01-02 16:26:32] hugoware

I'd say using certain system classes for extension methods is very handy, for example System.Enum, you can do something like below...

[Flags]
public enum ErrorTypes : int {
    None = 0,
    MissingPassword = 1,
    MissingUsername = 2,
    PasswordIncorrect = 4
}

public static class EnumExtensions {

    public static T Append<T> (this System.Enum type, T value) where T : struct
    {
        return (T)(ValueType)(((int)(ValueType) type | (int)(ValueType) value));
    }

    public static T Remove<T> (this System.Enum type, T value) where T : struct
    {
        return (T)(ValueType)(((int)(ValueType)type & ~(int)(ValueType)value));
    }

    public static bool Has<T> (this System.Enum type, T value) where T : struct
    {
        return (((int)(ValueType)type & (int)(ValueType)value) == (int)(ValueType)value);
    }

}

...

//used like the following...

ErrorTypes error = ErrorTypes.None;
error = error.Append(ErrorTypes.MissingUsername);
error = error.Append(ErrorTypes.MissingPassword);
error = error.Remove(ErrorTypes.MissingUsername);

//then you can check using other methods
if (error.Has(ErrorTypes.MissingUsername)) {
    ...
}

This is just an example of course - the methods could use a little more work...


(1) Nice; but I'd use Include instead of Append since Append implies an order which the values may not have. - devstuff
@devstuff - that is a good point, I didn't really ever think about it from that perspective. - hugoware
@HBoss: I'm gonna use that. It will make it so much easier to implement Flags the way we should be. - IAbstract
Just figured something awesome out: All those "object" casts are causing a lot of boxing. If you add a generic constraint of where T : struct (so that T can't be a reference type), you can actually cast (int)(ValueType)value and avoid the boxing: I've edited the answer to show this. - John Gibb
59
[+36] [2008-08-14 22:31:26] Luke Foust

Being able to have enum types have values other than int (the default)

public enum MyEnum : long
{
    Val1 = 1,
    Val2 = 2
}

Also, the fact that you can assign any numeric value to that enum:

MyEnum e = (MyEnum)123;

But the values have to be discreet. So no floats or doubles etc. Just for completeness' sake ;) - Boris Callens
(3) Why would you want to be able to assign just any old value to an enum? Isn't the point of an enum to limit the choices of values? - RobH
(4) I believe the compiler has to support this for the sake of supporting flags. So given the enum above, if you do MyEnum val = MyEnum.Val1 | MyEnum.Val2 you would end up with a value that is outside of the already defined possible values. (in this case 3). Since you can do binary arithmetic on enums they can theoretically have many possible values. - Luke Foust
(1) One good reason would be to match it to the ID column of a read-only bootstrap table in a database. - Aaronaught
Also, note that you can assign MyEnum e = (MyEnum)123;, but when you access e you'll get an Exception. - ANeves
(4) You can also have [Flags] to tell that the enum is flag based - SztupY
@RobH- I've found it useful in unit testing when needing to test some conditional logic and force it down a branch of an if-else (or switch) statement by using an invalid enum value. - Ray
@RobH - Say you have a local enum that maps to an enum of an external code, of an API for example. If a new value is added to the external type and you haven't updated your enum def, at least you can store the numeric value. Good for reference. - Sean
@ANeves: you will never get an exception. ToString() will return the numeric value instead of the name. The only way you'd know is if you used Enum.IsDefined(MyEnum, e), in which case you'd return false. - John Gibb
Like Luke Foust says, it's useful for flags. You can assign values 1, 2, 4, 8, 16...etc to the enums and thus add them up in a single int and use this to store a whole range of settings. - Pedery
@John Gibb: I know you can get an exception out of it, out of empirical experience. But I'm not managing to reproduce it now and don't have the code where I tested for that. (Changed work places in the meanwhile.) I was using enums to map numeric values to human-readable code, and one of the tests tested for that. PS: ...oooow poke. - ANeves
60
[+36] [2008-09-05 16:53:07] Judah Gabriel Himango

I just found out about this one today -- and I've been working with C# for 5 years!

It's the namespace alias qualifier [1]:

extern alias YourAliasHere;

You can use it to load multiple versions of the same type. This can be useful in maintenance or upgrade scenarios where you have an updated version of your type that won't work in some old code, but you need to upgrade it to the new version. Slap on a namespace alias qualifier [2], and the compiler will let you have both types in your code.

[1] http://msdn.microsoft.com/en-us/library/ms173212(VS.80).aspx
[2] http://blogs.msdn.com/abhinaba/archive/2005/11/30/498278.aspx

61
[+36] [2010-06-29 05:18:36] Keith Bluestone

RealProxy lets you create your own proxies for existing types.

This is super-advanced and I haven't seen anyone else use it -- which may mean that it's also really not that useful for most folks -- but it's one of those things that's good to know.

Basically, the .NET RealProxy class lets you create what is called a transparent proxy to another type. Transparent in this case means that it looks completely like the proxied target object to its client -- but it's really not: it's an instance of your class, which is derived from RealProxy.

This lets you apply powerful and comprehensive interception and "intermediation" services between the client and any methods or properties invoked on the real target object. Couple this power with the factory pattern (IoC etc), and you can hand back transparent proxies instead of real objects, allowing you to intercept all calls to the real objects and perform actions before and after each method invocation. In fact, I believe this is the very functionality .NET uses for remoting across app domain, process, and machine boundaries: .NET intercepts all access, sends serialized info to the remote object, receives the response, and returns it to your code.

Maybe an example will make it clear how this can be useful: I created a reference service stack for my last job as enterprise architect which specified the standard internal composition (the "stack") of any new WCF services across the division. The model mandated that the data access layer for (say) the Foo service implement IDAL<Foo>: create a Foo, read a Foo, update a Foo, delete a Foo. Service developers used supplied common code (from me) that would locate and load the required DAL for a service:

IDAL<T> GetDAL<T>(); // retrieve data access layer for entity T

Data access strategies in that company had often been, well, performance-challenged. As an architect, I couldn't watch over every service developer to make sure that he/she wrote a performant data access layer. But what I could do within the GetDAL factory pattern was create a transparent proxy to the requested DAL (once the common service model code located the DLL and loaded it), and use high-performance timing APIs to profile all calls to any method of the DAL. Ranking laggards then is just a matter of sorting DAL call timings by descending total time. The advantage to this over development profiling (e.g. in the IDE) is that it can be done in the production environment as well, to ensure SLAs.

Here is an example of test code I wrote for the "entity profiler," which was common code to create a profiling proxy for any type with a single line:

[Test, Category("ProfileEntity")]
public void MyTest()
{
    // this is the object that we want profiled.
    // we would normally pass this around and call
    // methods on this instance.
    DALToBeProfiled dal = new DALToBeProfiled();

    // To profile, instead we obtain our proxy
    // and pass it around instead.
    DALToBeProfiled dalProxy = (DALToBeProfiled)EntityProfiler.Instance(dal);

    // or...
    DALToBeProfiled dalProxy2 = EntityProfiler<DALToBeProfiled>.Instance(dal);

    // Now use proxy wherever we would have used the original...
    // All methods' timings are automatically recorded
    // with a high-resolution timer
    DoStuffToThisObject(dalProxy);

    // Output profiling results
    ProfileManager.Instance.ToConsole();
}

Again, this lets you intercept all methods and properties called by the client on the target object! In your RealProxy-derived class, you have to override Invoke:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
[SecurityPermission(SecurityAction.LinkDemand, 
    Flags = SecurityPermissionFlag.Infrastructure)] // per FxCop
public override IMessage Invoke(IMessage msg)
{
    IMethodCallMessage msgMethodCall = msg as IMethodCallMessage;
    Debug.Assert(msgMethodCall != null); // should not be null - research Invoke if this trips. KWB 2009.05.28

    // The MethodCallMessageWrapper
    // provides read/write access to the method 
    // call arguments. 
    MethodCallMessageWrapper mc =
        new MethodCallMessageWrapper(msgMethodCall);

    // This is the reflected method base of the called method. 
    MethodInfo mi = (MethodInfo)mc.MethodBase;

    IMessage retval = null;

    // Pass the call to the method and get our return value
    string profileName = ProfileClassName + "." + mi.Name;

    using (ProfileManager.Start(profileName))
    {
        IMessage myReturnMessage =
           RemotingServices.ExecuteMessage(_target, msgMethodCall);

        retval = myReturnMessage;
    }

    return retval;
}

Isn't it fascinating what .NET can do? The only restriction is that the target type must be derived from MarshalByRefObject. I hope this is helpful to someone.


I've used RealProxy before to produce detailed logs of COM interop conversations... Very handy when you want to give a supplier a picture of exactly where their component is failing! I only wish it was possible to use this on objects of any type... - Shog9
Yes, I agree, and not completely sure why the MarshalByRefObject restriction exists... - Keith Bluestone
Thanks for the detailed explanation! Although this is not really a feature of the C# language. - M4N
Yep, that's what Remoting is based on. And I once tried to use it, to do some Remoting interception. For some easy interception scenarios that can be very nice. Unfortunately, I learned that there are some limitations deep inside and .Net internals are occasionally vicious, so be wary :) - akavel
The type can also be an interface, not just MarshalByRefObject - Pop Catalin
62
[+35] [2010-03-22 20:05:06] John K

Arbitrary nested scopes { }


1. For finer scoping behaviour

{ anywhere inside members }, { using only braces }, { with no control statement }.

void MyWritingMethod() {

    int sameAge = 35;


    { // scope some work
        string name = "Joe";
        Log.Write(name + sameAge.ToString());
    }


    { // scope some other work
        string name = "Susan";
        Log.Write(name + sameAge.ToString());
    }

    // I'll never mix up Joe and Susan again
}

Inside large, confusing or archaic members (not that they should ever exist, however,) it helps me prevent against using wrong variable names. Scope stuff to finer levels.

2. For code beautification or visual semantics

For example, this XML writing code follows the indentation level of the actual generated XML (i.e. Visual Studio will indent the scoping braces accordingly)

XmlWriter xw = new XmlWriter(..);

//<root>
xw.WriteStartElement("root");
{
    //<game>
    xw.WriteStartElement("game");
    {
        //<score>#</score>
        for (int i = 0; i < scores.Length; ++i) // multiple scores
            xw.WriteElementString("score", scores[i].ToString());

    }
    //</game>
    xw.WriteEndElement();
}
//</root>
xw.WriteEndElement();

3. Mimic a 'with' statement

(Also another use to keep temp work out of the main scope)
Provided by Patrik [1]: sometimes used to mimic the VB "with-statement" in C#.

var somePerson = this.GetPerson();  // whatever 
{ 
    var p = somePerson; 
    p.FirstName = "John"; 
    p.LastName = "Doe"; 
    //... 
    p.City = "Gotham"; 
} 

For the discerning programmer.

[1] https://stackoverflow.com/users/46187/

This is something I've sometimes used to mimic the VB "with-statement" in C#. var somePerson = this.GetPerson(); // whatever { var p = somePerson; p.FirstName = "John"; p.LastName = "Doe"; //... p.City = "Gotham"; } - Patrik Hägne
(1) +1, I have done this before. However it only served to confuse my coworkers. The example with the xml writer is pretty sweet though. I would do a scores.ForEach(...) though to make the indentation right. - Bill Barry
One place I like to use this is between a Debug.Indent() and a Debug.Unindent(). Gives a good visual in the code of what's happening. - Ryan Lundy
(1) var xdoc = new XDocument( new XElement("root", new XElement("game", scores.Select(score => new XElement("score", score.ToString()))))); // apologies for lack of formatting - hosed by SO - David Clarke
I just don't see how this is a language feature - sehe
63
[+34] [2008-08-18 23:47:06] Rismo

Not hidden, but I think that a lot of developers are not using the HasValue and Value properties on the nullable types.

        int? x = null;
        int y;
        if (x.HasValue)
            y = x.Value;

(2) How would one employ a nullable type without using HasValue? - Cheeso
(4) Like this: int? x; if(x != null) - Rismo
(14) No, people like to write: y = x ?? defaultvalue. - Dave Van den Eynde
(12) Just to be clear, (x != null) and (x.HasValue) result in identical IL. - snarf
(4) I prefer x != null over x.HasValue. - ANeves
x!= null is preferable in a generic method where the method may receive either a non-nullable or a nullable. In either case, casting as object will allow you to get at the value without .HasValue which the non-nullable value doesn't have. - BenAlabaster
Is there a difference between y = x.Value and y = (int)x? - Justin Morgan
@Snarfblam it's interesting to point out that nullables are special cased by the .Net boxing code. For example, an Nullable<int> with a value will be boxed as an int, but a Nullable<int> without a value will actually be boxed as a null. If you wrote your own Nullable class, it would be boxed as a YourNullable<int> either way, and a comparison with null would NEVER be equal (since there actually IS a boxed value on the heap). - John Gibb
Way too much typing ... y = x.HasValue ? x.Value : y or y = x ?? y... - Jeroen Landheer
when trying ?? operator we need to typecast the type sometimes.like int? i; - PraveenLearnsEveryday
64
[+33] [2008-08-15 11:34:02] Surgical Coder

My favourite is the

global::

keyword to escape namespace hell with some of our 3rd party code providers...

Example:

global::System.Collections.Generic.List<global::System.String> myList =
    new global::System.Collections.Generic.List<global::System.String>();

(1) It works just like an access specifier but with respect to namespaces i.e. global when used with the namespace alias qualifier :: refers to the global namespace, which is the default namespace for any C# program. Example usage here - msdn.microsoft.com/en-us/library/c3ay4x3d.aspx - Robin Maben
65
[+31] [2009-07-11 19:01:09] Yvo

I've read through all seven pages, and I'm missing these:

String.Join

I've seen a lot of for-loops to convert a list of items to a string with separators. It's always a pain to make sure you doin't start with a separator and don't end with a separator. A built-in method makes this easier:

String.Join(",", new String[] { "a", "b", "c"});

TODO in comment

Not really a C# feature, more of a Visual Studio feature. When you start your comment with TODO, it's added to your Visual Studio Task List (View -> Task List. Comments)

// TODO: Implement this!
throw new NotImplementedException();

Extension methods meets Generics

You can combine extension methods with Generics, when you think of the tip earlier in this topic, you can add extensions to specific interfaces

public static void Process<T>(this T item) where T:ITest,ITest2 {}

Enumerable.Range

Just want a list of integers?

Enumerable.Range(0, 15)

I'll try to think of some more...


(8) it is indeed a VS tip, but besides TODO, we also use: QUESTION, HACK, BUG, FIX, REFACTOR, RESOURCE: (with the url from where you got a tip/code) You can add as many as you want through Tools>Options>Task List And with a CI like Hudson that picks these up it's great! - Cohen
In fact, you can add an extension method to everything with the generic extension methods... - RCIX
RCIX, that's right but what would be the use of Generics? You could just define an extension method for object. - Yvo
String.Join and Enumerable.Range remind me of Python's equivalents: ",".join(["a", "b", "c"]) and range(0, 15). - Ray
(3) The Enumerable.Range can be used as an alternative to a for loop. Instead of doing this for(i = 0; i < 15; i++), you can do this foreach (int i in Enumerable.Range(0, 15)). - Ray
66
[+31] [2009-09-12 19:47:40] codymanix

You can "use" multiple objects in one using statement.

using (Font f1= new Font("Arial", 10.0f), f2 = new Font("Arial", 10.0f))
{
    // Use f1 and f2.
}

Note that there is already an answer stating that you can do this:

using (Font f1= new Font("Arial", 10.0f))
using (Font f2 = new Font("Arial", 10.0f))
{    }

Which is different from mine.


(1) You probably can't use your method if f2 depends on f1, right? I use the second method all the time where you "use" an NHibernate ISession and then use that to build an NHibernate ITransaction, which is also disposable. - Scott Whitlock
(3) Note that you can only specify multiple objects in the same using statement if they are of the same type. - David Clarke
does this also contain the same disposal gotcha as property initializers in a using clause? where if one of the things in the using clause throws an exception, so something doesn't get disposed. - Maslow
67
[+31] [2010-05-27 03:10:14] Kim Tranjan

Width in string.Format()

Console.WriteLine("Product: {0,-7} Price: {1,5}", product1, price1);
Console.WriteLine("Product: {0,-7} Price: {1,5}", product2, price2);

produces

alt text

from Prabir's Blog | Hidden C# feature [1]

[1] http://blog.prabir.me/post/Hidden-C-feature-stringFormat-Width.aspx

68
[+31] [2010-06-13 05:14:40] Buildstarted

typedefs

Someone posted that they miss typedefs but you can do it like this

using ListOfDictionary = System.Collections.Generic.List<System.Collections.Generic.Dictionary<string, string>>;

and declare it as

ListOfDictionary list = new ListOfDictionary();

(10) Just keep in mind that this method is scoped, at best, for the current file. You will need to add this to the top of every file in your project. - Matthew Scharley
It is not a hidden feature. It's completely documented in the specification. - Lyubomyr Shaydariv
(13) @Lyubomyr and so are 90% of answers to this question. - C. Ross
Typedef is a compilation solution and it's looks like this solution is a runtime. The result is clearly not the same in therms of performances ... - Nicolas Guillaume
(3) Niklaos, checking the Il it's a compile time substitution and not something at runtime. - Buildstarted
69
[+30] [2008-09-08 12:49:17] nialljsmith

I like the keyword continue.

If you hit a condition in a loop and don't want to do anything but advance the loop just stick in "continue;".

E.g.:

foreach(object o in ACollection)
{
  if(NotInterested)
     continue;
}

(3) -1: Use of continue's, break's etc. are one step away from goto's (which are evil). They make the flow of execution difficult to follow in complex programs and will eventually lead you to writing spaghetty code. - Jon Cage
(57) +1 to offset Jon Cage. If continue/break are evil, then so is return. continue/break can be used to terminate a loop early (continue terminates just the current iteration, break terminates the entire loop), just as return can be used to terminate a function early. And early out can be much better than deeply-nested ifs. And goto is not evil, just not often necessary. It got a bad rep from the "spaghetti code" often created in older languages lacking better constructs. Having these better constructs leads to cleaner code and much less need for goto, but not none. Use the right tool for the job. - P Daddy
(17) +1 to doubly offset Jon Cage. Partially because he can't spell spaghetti. Using continue, break, and goto are perfectly valid means to an end. If you're using them excessively, you're probably doing something wrong, but code does call for it at times. If a developer has a hard time following that, they should probably look for a new profession as gotos are at the ancestral roots of a lot of modern programming, if anyone remembers BASIC. - Ben Lesh
(3) +1 to triple the offset: while I might use if(!NotInterested){...} in the example, I would not drag break into this. break is required by switch-case, and to escape out of a loop when a condition is met. return is just as important to stopping a function from continuing as is break within an interation. - IAbstract
@blesh I remember basic... on my old Acorn A3000. ;D - user246091
(1) I agree that continue is wonderful, but I don't see how this is a hidden language feature? I've been using it since day one. - Ozzah
+1 Quads on JC - continue, break, and goto all have their place. For example in switch statements when you wish to fall-through...Non-structured flow is necessary for many algorithms. It's not evil, just complex. - Fraser
70
[+28] [2008-08-12 16:37:19] TheSmurf

Two of my personal favourites, which I see rarely used:

  1. Snippets (particularly for properties, which was made even better for Visual Studio 2008)
  2. The ObsoleteAttribute [1]
[1] http://msdn.microsoft.com/en-us/library/system.obsoleteattribute.aspx

(2) I like the switch snippet very much. Makes switching on an enum sooo much easier ;) - OregonGhost
i regularly use a snippet for Properties calling OnPropertyChanged in the setter. very handy. - Botz3000
(2) Are snippets though a feature of Visual Studio? Rather than C#/compiler? - maxwellb
(1) snippets are part of visual studio shortcut is ctrl - k+ctrl x - Maslow
(4) better yet eg: write "for" or "switch" and then double-press 'tab' key - murki
very handy indeed both with Ctrl-K + Ctrl-X and double tab on "for", "while", "foreach", "if", etc. - devXen
Yep, like obsolete for refactoring to highlight code I'm trying to make go away. - David Clarke
71
[+28] [2008-08-19 04:41:58] xanadont

@lomaxx I also learned the other day (the same time I learned your tip) is that you can now have disparate access levels on the same property:

public string Name { get; private set;}

That way only the class itself can set the Name property.

public MyClass(string name) { Name = name; }

This syntax was added to c# in 2.0. C++ allowed it on .Net 1.0 and 1.1 - Bert Huijben
Unfortunately this is the only applicable combination of distinct access rights, 'get; internal set;' would not work - Simon D.
How do you figure? This compiled for me fine just now: public string Foo { get; internal set; } - xanadont
(4) protected set; is really useful for base classes. - Arnis Lapsa
What would the point of a private property be anyway? what's wrong with 'this.Name='? - Bryan
72
[+28] [2008-09-01 05:03:20] jfs

Nesting Using Statements

Usually we do it like this:

StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter()) {
    using (IndentedTextWriter itw = new IndentedTextWriter(sw)) {
        ... 
    }
}

But we can do it this way:

StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter())
using (IndentedTextWriter itw = new IndentedTextWriter(sw)) {
    ... 
}

(8) Is this a feature specific to the using keyword? It just looks like the typical syntax where a statement (such as if, using, while) operates on either the next statement or statement block. Omitting the curly braces in these situations is not recommended in the code style guides I've read. - J c
(2) Its's not specific to using, you can write: if(Something) using(new Pen()) using(new Brush())for(;;)DoSometing(); - Olmo
I agree...not a terribly good practice. I'm always very wary of omitting curly braces for maintainability purposes. For my own practices, if I have a single line statement to be used inside a block like that, I always turn it into one line, like if(bool) doStuff(); - Adam Robinson
(3) You can do this with every statement that can be nested. - user65199
What's the difference? It's the same because you only have 1 block after the statement (same as the difference between: if (condition) { if (condition2) { } } and: if (condition) if (condition2) - Nissim
Tbh, imho, this is in absolutely no respect a "hidden" "feature" to non-beginner programmers. See Hermann's answer. I.e., then if(x)using(var y=...) could be considered a feature, too, as could "if(true)while(true)using(var x=...)switch(0){default:break}return;" - Sebastian Mach
I use this to avoid unnecessary nesting but it's a bit smelly (as per Nissim's comment above) - David Clarke
73
[+28] [2009-09-09 11:31:54] cllpse

JavaScript-like anonymous inline-functions

Return a String:

var s = new Func<String>(() =>
{
    return "Hello World!";
})();

Return a more complex Object:

var d = new Func<Dictionary<Int32, String>>(() =>
{
    return new Dictionary<Int32, String>
    {
        { 0, "Foo" },
        { 1, "Bar" },
        { 2, "..." }
    };
})();

A real-world use-case:

var tr = new TableRow();

tr.Cells.AddRange
(
    new[]
    {
        new TableCell { Text = "" },
        new TableCell { Text = "" },
        new TableCell { Text = "" },

        new TableCell
        {
            Text = new Func<String>(() =>
            {
                return @"Result of a chunk of logic, without having to define
                         the logic outside of the TableCell constructor";
            })()
        },

        new TableCell { Text = "" },
        new TableCell { Text = "" }
    }
);

Note: You cannot re-use variable names inside the inline-function's scope.


Alternative syntax

// The one-liner
Func<Int32, Int32, String> Add = (a, b) => Convert.ToString(a + b);

// Multiple lines
Func<Int32, Int32, String> Add = (a, b) =>
{
    var i = a + b;

    return i.ToString();
};

// Without parameters
Func<String> Foo = () => "";

// Without parameters, multiple lines
Func<String> Foo = () =>
{
    return "";
};

Shorten a string and add horizontal ellipsis...

Func<String, String> Shorten = s => s.Length > 100 ? s.Substring(0, 100) + "&hellip;" : s;

74
[+27] [2008-08-17 21:13:24] Mark Cidade

There's also the ThreadStaticAttribute to make a static field unique per thread, so you can have strongly typed thread-local storage.

Even if extension methods aren't that secret (LINQ is based on them), it may not be so obvious as to how useful and more readable they can be for utility helper methods:

//for adding multiple elements to a collection that doesn't have AddRange
//e.g., collection.Add(item1, item2, itemN);
static void Add<T>(this ICollection<T> coll, params T[] items)
 { foreach (var item in items) coll.Add(item);
 }

//like string.Format() but with custom string representation of arguments
//e.g., "{0} {1} {2}".Format<Custom>(c=>c.Name,"string",new object(),new Custom())
//      result: "string {System.Object} Custom1Name"
static string Format<T>(this string format, Func<T,object> select, params object[] args)
 { for(int i=0; i < args.Length; ++i)
    { var x = args[i] as T;
      if (x != null) args[i] = select(x);
    }
   return string.Format(format, args);
 }

75
[+27] [2008-10-10 16:22:40] IgorM

Full access to the call stack:

public static void Main()
{
  StackTrace stackTrace = new StackTrace();           // get call stack
  StackFrame[] stackFrames = stackTrace.GetFrames();  // get method calls (frames)

  // write call stack method names
  foreach (StackFrame stackFrame in stackFrames)
  {
    Console.WriteLine(stackFrame.GetMethod().Name);   // write method name
  }
}

So, if you'll take the first one - you know what function you are in. If you're creating a helper tracing function - take one before the last one - you'll know your caller.


(2) One thing that might trip you up is if you're in Debug or Release mode. The stack trace can differ due to optimizations. This screwed me up in an ill-fated attempt to regulate the callers of certain methods: moffdub.wordpress.com/2008/07/01/method-regulator-pattern - moffdub
(2) you can use <System.Runtime.CompilerServices.MethodImpl(Runtime.Compiler‌​Services.MethodImplO‌​ptions.NoInlining)> to help with this problem. - Maslow
@Maslow: Thanks, that helped me solve a problem and make our security system much easier to use. - JohannesH
@moffdub @JohannesH Checking up the stack to see who the caller is for security purposes seems farily dubious. Certainly in C it's trivial to make it look like some benign code is calling you -- it wouldn't surprise me if the same is true of .NET - asveikau
@asveikau: You obviously aren't familiar with the CLR's code access security model or you wouldn't say that. The security on NET Framework CLR's runtime stack is very carefully and tightly controlled, since it forms the basis for NET Framework's security model. Specifically, managed code has absolutely zero ability to manipulate it at all. - Ray Burns
@Ray Burns - Fair enough for you to say I'm not all that familiar with managed code.. However I do recall reading about some exploits of Java's (not .NET but close) stack-based security model. And certainly a naively implemented policy based on a walk of the stack (not as part of the language runtime, but something say in a third-party library as a misguided security feature) has great potential for misuse. - asveikau
(1) This is not really a language feature, but a framework feature - codymanix
76
[+27] [2008-11-18 16:16:26] Bryan Watts

On-demand field initialization in one line:

public StringBuilder Builder
{
    get { return _builder ?? (_builder = new StringBuilder()); }
}

I'm not sure how I feel about C# supporting assignment expressions, but hey, it's there :-)


I'm disappointed, so many years coding in .NET without using this syntax... Great ! - Nicolas Dorier
Unfortunately this feature is duped. Saw the same above. - Arnis Lapsa
It isn't anymore in .NET 3.5. - Joop
I'm fairly certain you are mistaken. I didn't see anything on a Google search and I would be very surprised if C# made a breaking syntax change of any kind. - Bryan Watts
I don't think I like this, especially for privates. It's a good technique for exposing publics though. I'd prefix it with 'Summon' though, for instance, SummonBuilder (stevedunns.blogspot.com/2010/04/summon-method.html) - Steve Dunn
Funny side note, if you look up this property in reflector, you'll get a "this code has been obfuscated". At least the last time I tried (~ 6 months ago). - John Gibb
77
[+27] [2009-11-24 13:15:08] Roman Boiko

Easily determine type with which variable was declared (from my answer [1]):

using System;
using System.Collections.Generic;

static class Program
{
    public static Type GetDeclaredType<T>(T x)
    {
        return typeof(T);
    }

    // Demonstrate how GetDeclaredType works
    static void Main(string[] args)
    {
        IList<string> iList = new List<string>();
        List<string> list = null;

        Console.WriteLine(GetDeclaredType(iList).Name);
        Console.WriteLine(GetDeclaredType(list).Name);
    }
}

Results:

IList`1
List`1

And its name (borrowed from "Get variable name" [2]):

static void Main(string[] args)
{
    Console.WriteLine("Name is '{0}'", GetName(new {args}));
    Console.ReadLine();
}

static string GetName<T>(T item) where T : class
{
    var properties = typeof(T).GetProperties();
    return properties[0].Name;
}

Result: Name is 'args'

[1] https://stackoverflow.com/questions/1786750/how-to-know-in-c-code-which-type-a-variable-was-declared-with/1786775#1786775
[2] https://stackoverflow.com/questions/1386642/get-variable-not-hard-coded-name/1386730#1386730

(2) Actually, not bad. The first look at the sample is misleading. I'll remember this trick. :) - Lyubomyr Shaydariv
Cant you simply write Console.WriteLine(iList.GetType().Name);? - user34537
(2) @acidzombie24: You'll get List'1 as the first result, not IList'1. And null-reference exception instead of the second result. GetType() returns type of an object, not declared type of variable. - Roman Boiko
Will that work in C# 2.0 or earlier also? not sure if generic type inference was there before 3.0. - Manish Basantani
Generics are there since C# (and .NET) 2.0. Type inference is specific for C# 3.0 and doesn't depend on version of .NET. If you have compiler for C# 3.0 or later version, you can build for target framework .NET 2.0 and it will work. The same is true for the second example, where the anonymous types are used: new {args}. They are available since C# 3.0, and this code can be built for .NET 2.0 using C# 3.0 compiler. About anonymous types see also csharpindepth.com/Articles/General/BluffersGuide3.aspx - Roman Boiko
78
[+26] [2008-08-18 14:43:56] juan

It's not actually a C# hidden feature, but I recently discovered the WeakReference class [1] and was blown away by it (although this may be biased by the fact that it helped me found a solution to a particular problem of mine [2]...)

[1] http://msdn.microsoft.com/en-us/library/system.weakreference.aspx
[2] http://www.juanformoso.com.ar/post/2008/07/30/Weak-References.aspx

+1 - you may be interested to know this seems to be used in the MVVMLight Toolkit in the Message Passing part. - Scott Whitlock
79
[+26] [2008-10-08 07:45:04] GvS

The Environment.UserInteractive [1] property.

The UserInteractive property reports false for a Windows process or a service like IIS that runs without a user interface. If this property is false, do not display modal dialogs or message boxes because there is no graphical user interface for the user to interact with.

[1] http://msdn.microsoft.com/en-us/library/system.environment.userinteractive.aspx

+1 nice for reducing "progress update" slowdowns - chakrit
Definitely sounds useful for building services or command line utilities. - John B
@SkippyFire: Not for command-line utilities. A console application is still user-interactive, and can still create message boxes or any other GUI elements, btw. The only difference between a so-called "Windows Application" and a "Console Application" is that a console app creates a console window or attaches to one if run a command-line. - P Daddy
80
[+26] [2009-08-07 06:44:19] Jason Williams

Programmers moving from C/C++ may miss this one:

In C#, % (modulus operator) works on floats!


It is still bound by the inaccuracies of floating point logic. If you really want an accurate modulus when using a decimal number, you should use Decimal. - Nellius
81
[+26] [2010-06-30 04:20:12] Incognito

AppDomain.UnhandledException Event [1] is also candidate for being hidden.

This event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application. If sufficient information about the state of the application is available, other actions may be undertaken — such as saving program data for later recovery. Caution is advised, because program data can become corrupted when exceptions are not handled.

We can see, even on this site, a lot of people are wondering why their application is not starting, why it crashed, etc. The AppDomain.UnhandledException event can be very useful for such cases as it provides the possibility at least to log the reason of application failure.

[1] http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx

There is more to know about: stackoverflow.com/questions/219594/net-whats-the-best-way-to‌​- implement-a-catch-all-exceptions-handler - bohdan_trotsenko
82
[+25] [2008-08-26 12:54:41] Frep D-Oronge

The C# ?? null coalescing operator -

Not really hidden, but rarely used. Probably because a lot of developers run a mile when they see the conditional ? operator, so they run two when they see this one. Used:

string mystring = foo ?? "foo was null"

rather than

string mystring;
if (foo==null)
    mystring = "foo was null";
else
    mystring = foo;

I understand your point, but the second example could be shortened without using the ?? operator. Just like string mystring = foo == null? "foo was null" : foo; Still long, I admit, but at least a bit shorter. - luiscubal
(3) If the condition is a function that computes a result, with the ternary operator you would end up calling the function twice (in the case it evaluates to true). Whereas using ?? will only call it once. - dso
Thanks for this! I have always used ? the traditional way as mystring = foo.IsNullOrEmpty() ? "foo was null" : foo; since the time I first read about ternary operators and thought I was so cool! Until, now.. :P - Robin Maben
83
[+25] [2008-08-26 22:19:01] Robert Durgin

The #if DEBUG pre-processor directive. It is Useful for testing and debugging (though I usually prefer to go the unit testing route).

string customerName = null;
#if DEBUG
  customerName = "Bob"
#endif

It will only execute code block if Visual Studio is set to compile in 'Debug' mode. Otherwise the code block will be ignored by the compiler (and grayed out in Visual Studio).


(3) Note that you can define any symbol and then use conditional compilation on that symbol. DEBUG just happens to be automatically defined for you by default. - xanadont
(11) [Conditional("DEBUG")]-marked methods usually make for cleaner, easier to read code. - Danut Enachioiu
Good stuff. Saved me some trouble because when I publish on our network Drive D: is the needed path rather than Drive C: that I use on my local machine. Been burned in the past when I forgot to change it back! - Darcy
84
[+25] [2010-01-25 13:55:03] Mohammad Tayseer

I didn't find anyone who is using string.Join to join strings using a separator. Everyone keeps writing the same ugly for-loop

var sb = new StringBuilder();
var count = list.Count();
for(int i = 0; i < count; i++)
{
  if (sb.Length > 0) sb.Append(seperator);
  sb.Append(list[i]);
}

return sb.ToString();

instead of

return string.Join(separator, list.ToArray());

(1) you forgot if (sb.Length > 0) sb.Append(seperator); to remove the preceding separator. You also want to cache any Count() functions to save re-evaluations and string.Join() is only for arrays. Like many others devs I have my own extension methods which is cleaner that string.Join() - mythz
I fixed the errors. My point is that I see the former piece of code more than I find the later - Mohammad Tayseer
(3) In .Net 4 String.Join works with IEnumerable so you don't need to convert to an array first. - David Clarke
85
[+24] [2008-08-19 15:23:12] Jon Erickson

Partial Methods

Charlie Calvert explains partial methods on his blog [1]

Scott Cate has a nice partial method demo here [2]

  1. Points of extensibility in Code Generated class (LINQ to SQL, EF)
  2. Does not get compiled into the dll if it is not implemented (check it out with .NET Reflector)
[1] http://blogs.msdn.com/charlie/archive/2007/11/11/partial-methods.aspx
[2] http://weblogs.asp.net/scottcate/archive/2008/06/18/teched-orlando-compiler-tricks.aspx

I dunno, Partial methods have always seemed like a code smell to me... - George Mauer
In a lot of cases perhaps. Good for separating generated code from developer code though. - BlackWasp
(1) I use this to produce multiple versions of an assembly. Some versions are endowed with extra magic capabilities, and some are not. I embed the methods that perform the magic in a separate code module, and mark them partial. Then, I can call them from the primary code module, without worrying which version of the assembly it is, and without #if conditionals. - Cheeso
I use it just the way BlackWasp does;PartialMethod++ == Delegate-- == Speed * 2; - Behrooz
I didn't know you can tag the partial keyword to a method, interesting... Still I don't think I'll use it... yet. I do rely heavily on partial for auto generated classes, but this implies that the auto generated classes aren't complete until I've filled in the partial method. I wonder whether there wouldn't have been a better way to write the app which generates the classes. - Christo
86
[+24] [2008-08-28 12:55:57] Jakub Šturc

true [1] and false [2] operators are really weird.

More comprehensive example can be found here [3].

Edit: There is related SO question What’s the false operator in C# good for? [4]

[1] http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx
[2] http://msdn.microsoft.com/en-us/library/6292hy1k.aspx
[3] http://www.java2s.com/Tutorial/CSharp/0160__Operator-Overload/truefalseoperatorforComplex.htm
[4] https://stackoverflow.com/questions/33265/whats-the-false-operator-in-c-good-for

(2) Been working with C# for 5 years and have never seen the true operator being overloaded. Makes sense since you can overload arithmetic and equality operators. Thanks! - Judah Gabriel Himango
nice, never thought of that. Can be useful in some cases... - Sorskoot
One thing I didn't get is when false operator is called. - HuBeZa
You can use this operators to shorten the null check syntax: class MyClass { public static bool operator true(MyClass o) { return o != null; } public static bool operator false(MyClass o) { return o == null; } public static bool operator !(MyClass o) { return o ? false : true; } } - HuBeZa
I've seen some libraries that use this feature. Personally, I can find a few good uses, but I still like to express the condition explicitely, because the question "Is bannana" does not explain the purpose, while "Does bannana exist" (bannana != null) does explain the condition. Especially if you are writing the code that other will use. - Kornelije Petak
(1) @HuBeZa: see stackoverflow.com/questions/33265/… - Jakub Šturc
87
[+24] [2008-09-05 07:49:27] Pop Catalin

There are some really hidden keywords and features in C# related to the TypedReference undocumented class. The following keywords are undocumented:

  • __makeref
  • __reftype
  • __refvalue
  • __arglist

Examples of use:

// Create a typed reference
int i = 1;
TypedReference tr1 = __makeref(i);
// Get the type of a typed reference
Type t = __reftype(tr1);
// Get the value of a typed referece
int j = __refvalue(tr1, int); 
// Create a method that accepts and arbitrary number of typed references
void SomeMethod(__arglist) { ...
// Call the method
int x = 1;
string y = "Foo";
Object o = new Object();
SomeMethod(__arglist(x,y,o));
// And finally iterate over method parameters
void SomeMethod(__arglist) {
    ArgIterator ai = new ArgIterator(__arglist);
while(ai.GetRemainingCount() >0)
{
      TypedReference tr = ai.GetNextArg();
      Console.WriteLine(TypedReference.ToObject(tr));
}}

Why would you want to use these hidden undocumented keywords. They are likely hidden and undocumented for a reason, meaning they could change at any time. In my opinion this is risky. - Jon
(3) Yes it is risky to use them, these hidden keywords, were introduced before generics to make interop,P/Invoke faster, because these features let you avoid boxing/unboxing value types. - Pop Catalin
But I'd also like to add that these keywords are used in BCL sources, so until MS rewrites the BCL (which won't happen till next version .Net CLR), they are rather safe use, if you're willing to do some rewriting posibly to run on CLR past 2.x. - Pop Catalin
Interesting, but what is it good for? - Qwertie
@Qwertie, it is for passing variable length list of arguments using the stack and not a params array which is heap allocated. (Basically for faster interop code, that doesn't allocate heap arrays). bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx also check this blog post - Pop Catalin
88
[+23] [2009-11-30 15:37:31] Roman Boiko

I found that only few developers know about this feature.

If you need a method that works with a value-type variable via some interface (implemented by this value type), it's easy to avoid boxing during the method call.

Example code:

using System;
using System.Collections;

interface IFoo {
    void Foo();
}
struct MyStructure : IFoo {
    public void Foo() {
    }
}
public static class Program {
    static void MethodDoesNotBoxArguments<T>(T t) where T : IFoo {
        t.Foo();
    }
    static void Main(string[] args) {
        MyStructure s = new MyStructure();
        MethodThatDoesNotBoxArguments(s);
    }
}

IL code doesn't contain any box instructions:

.method private hidebysig static void  MethodDoesNotBoxArguments<(IFoo) T>(!!T t) cil managed
{
  // Code size       14 (0xe)
  .maxstack  8
  IL_0000:  ldarga.s   t
  IL_0002:  constrained. !!T
  IL_0008:  callvirt   instance void IFoo::Foo()
  IL_000d:  ret
} // end of method Program::MethodDoesNotBoxArguments

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       15 (0xf)
  .maxstack  1
  .locals init ([0] valuetype MyStructure s)
  IL_0000:  ldloca.s   s
  IL_0002:  initobj    MyStructure
  IL_0008:  ldloc.0
  IL_0009:  call       void Program::MethodDoesNotBoxArguments<valuetype MyStructure>(!!0)
  IL_000e:  ret
} // end of method Program::Main

See Richter, J. CLR via C# [1], 2nd edition, chapter 14: Interfaces, section about Generics and Interface Constraints.

See also my answer [2] to another question.

[1] http://rads.stackoverflow.com/amzn/click/0735621632
[2] https://stackoverflow.com/questions/1816419/does-passing-a-struct-into-an-interface-field-allocate/1817137#1817137

and why not just put 'Where T : struct' to avoid boxing... - AwkwardCoder
(3) @AWC: the task is to pass an instance of some interface into our method. So that we can call methods of this interface on a passed instance. Declarations like void BoxingMethod(IFoo x) cause boxing if x is a value type. Your example doesn't allow calls of interface methods. Code above allows such calls without boxing. - Roman Boiko
89
[+22] [2008-08-18 23:08:35] mgsloan

Near all the cool ones have been mentioned. Not sure if this one's well known or not

C# property/field constructor initialization:

var foo = new Rectangle() 
{ 
    Fill = new SolidColorBrush(c), 
    Width = 20, 
    Height = 20 
};

This creates the rectangle, and sets the listed properties.

I've noticed something funny - you can have a comma at the end of the properties list, without it being a syntax error. So this is also valid:

var foo = new Rectangle() 
{ 
    Fill = new SolidColorBrush(c), 
    Width = 20, 
    Height = 20,
};

(8) The comma at the end makes fiddling with the values much easier :) - OregonGhost
The trailing comma is also useful for generated code. You'll note that it holds for many situations. I run across it most often when making an enum. :) - Greg D
Enums also support the trailing comma "feature". - John B
(6) You don't need the () in Rectangle() either - rball
90
[+21] [2008-08-13 08:29:09] Will Dean

On the basis that this thread should be entitled "things you didn't know about C# until recently despite thinking you already knew everything", my personal feature is asynchronous delegates.

Until I read Jeff Richter's C#/CLR book (excellent book, everyone doing .NET should read it) I didn't know that you could call any delegate using BeginInvoke / EndInvoke. I tend to do a lot of ThreadPool.QueueUserWorkItem calls (which I guess is much like what the delegate BeginInvoke is doing internally), but the addition of a standardised join/rendezvous pattern may be really useful sometimes.


Yes BeginInvoke/EnInvoke uses the threadpool, I learned that in this forum. See stackoverflow.com/questions/442991/… and msdn.microsoft.com/en-us/library/2e08f6yc.aspx . - tuinstoel
(1) "things you didn't know about C# until recently despite thinking you already knew everything" +1 - corymathews
91
[+21] [2008-11-18 20:51:07] open-collar

Several people have mentioned using blocks, but I think they are much more useful than people have realised. Think of them as the poor man's AOP tool. I have a host of simple objects that capture state in the constructor and then restore it in the Dispose() method. That allows me to wrap a piece of functionality in a using block and be sure that the state is restored at the end. For example:

using(new CursorState(this, BusyCursor));
{
    // Do stuff
}

CursorState captures the current cursor being used by form, then sets the form to use the cursor supplied. At the end it restores the original cursor. I do loads of things like this, for example capturing the selections and current row on a grid before refreshing and so on.


(1) I used this trick once, and it ended up being useless because Win32 does something to restore the cursor for you, at least in WinForms - Olmo
I've just declared class called DisposableAction that takes action in constructor and executes it on the disposal. Really convenient. build.lokad.com/doc/shared/html/E5642EA0.htm - Rinat Abdullin
It is a bit cleaner than the try-finally approach that I find myself using. - Greg D
This is a useful way to implement certain internal DSLs. You can change the context of a bunch of declarative statements by encapsulating them in a using block. - Scott Whitlock
(1) Is it just me, or there is an extra semicolon? - Tom Pažourek
(1) You're right - there is an extra semicolon - it's taken nearly three years for someone to spot! - open-collar
92
[+21] [2010-06-22 16:12:29] Bill Barry

Another note on event handlers: you can simply create a raise extension method like so:

public static class EventExtensions {
    public static void Raise<T>(this EventHandler<T> @event, 
                                object sender, T args) where T : EventArgs {
        if(@event!= null) {
            @event(sender, args);
        }
    }
}

Then you can use it to raise events:

public class MyImportantThing {
    public event EventHandler<MyImportantEventEventArgs> SomethingHappens;
    ...
    public void Bleh() {
        SomethingHappens.Raise(this, new MyImportantEventEventArgs { X=true });
    }
}

This method has the added advantage of enforcing a coding standard (using EventHandler<>).

There isn't a point in writing the same exact function over and over and over again. Perhaps the next version of C# will finally have an InlineAttribute that can be placed on the extension method and will cause the compiler to inline the method definition (which would make this way nearly standard, and the fastest).

edit: removed temp variable inside extension method based on comments


You don't need the temp variable. It's used for avoiding an async change, but the event parameter is sufficient for that. - jpbochi
I am not so sure about that. The parameter is a reference type, so @event is the same object as the event in the class (unless there is something going on with the event syntax that I don't know about). Being that the assignment and checking code is recommended practice, I expect that the assignment operator is defined here to get around this problem. Regardless, it doesn't hurt to be safe. - Bill Barry
jpbochi is right, the temp variable does nothing. The parameter is a reference type, that's right but it's not passed by reference and there's a huge difference. Also, this extension works only for events using the the generic EventHandler delegate. When the generic delegate is used it's a neat trick though. - Patrik Hägne
93
[+20] [2008-08-27 21:05:41] Joel Coehoorn

I'm late to this party, so my first choices are already taken. But I didn't see anyone mention this gem yet:

Parallel Extensions to the .NET Framework [1]

It has things like replace with Parallel.For or foreach with Parallel.ForEach


Parallel Sample :
In your opinion, how many CLR object can be created in one second? enter image description here
See fallowing example :

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ObjectInitSpeedTest
{
   class Program
   {
       //Note: don't forget to build it in Release mode.
       static void Main()
       {
           normalSpeedTest();           
           parallelSpeedTest();

           Console.ForegroundColor = ConsoleColor.White;
           Console.WriteLine("Press a key ...");
           Console.ReadKey();
       }

       private static void parallelSpeedTest()
       {
           Console.ForegroundColor = ConsoleColor.Yellow;
           Console.WriteLine("parallelSpeedTest");

           long totalObjectsCreated = 0;
           long totalElapsedTime = 0;

           var tasks = new List<Task>();
           var processorCount = Environment.ProcessorCount;

           Console.WriteLine("Running on {0} cores", processorCount);

           for (var t = 0; t < processorCount; t++)
           {
               tasks.Add(Task.Factory.StartNew(
               () =>
               {
                   const int reps = 1000000000;
                   var sp = Stopwatch.StartNew();
                   for (var j = 0; j < reps; ++j)
                   {
                       new object();
                   }
                   sp.Stop();

                   Interlocked.Add(ref totalObjectsCreated, reps);
                   Interlocked.Add(ref totalElapsedTime, sp.ElapsedMilliseconds);
               }
               ));
           }

           // let's complete all the tasks
           Task.WaitAll(tasks.ToArray());

           Console.WriteLine("Created {0:N} objects in 1 sec\n", (totalObjectsCreated / (totalElapsedTime / processorCount)) * 1000);
       }

       private static void normalSpeedTest()
       {
           Console.ForegroundColor = ConsoleColor.Green;
           Console.WriteLine("normalSpeedTest");

           const int reps = 1000000000;
           var sp = Stopwatch.StartNew();
           sp.Start();
           for (var j = 0; j < reps; ++j)
           {
               new object();
           }
           sp.Stop();

           Console.WriteLine("Created {0:N} objects in 1 sec\n", (reps / sp.ElapsedMilliseconds) * 1000);
       }
   }
}
[1] http://msdn.microsoft.com/en-us/concurrency/default.aspx

It is not really a language feature, though, as it is just a library which uses other language features cleverly. - Morten Christiansen
94
[+20] [2008-12-05 11:10:09] community_owned

One great class I like is System.Xml.XmlConvert which can be used to read values from xml tag. Especially, if I am reading a boolean value from xml attribute or element, I use

bool myFlag  = System.Xml.XmlConvert.ToBoolean(myAttribute.Value);

Note: since boolean type in xml accepts 1 and 0 in addition to "true" and "false" as valid values, using string comparison in this case is error-prone.


95
[+20] [2009-06-02 07:20:56] Dave Van den Eynde

Atrribute Targets [1]

Everyone has seen one. Basically, when you see this:

[assembly: ComVisible(false)]

The "assembly:" portion of that attribute is the target. In this case, the attribute is applied to the assembly, but there are others:

[return: SomeAttr]
int Method3() { return 0; } 

In this sample the attribute is applied to the return value.

[1] http://msdn.microsoft.com/en-us/library/b3787ac0.aspx

96
[+20] [2009-09-23 09:00:29] rikoe

Apologies for posting so late, I am new to Stack Overflow so missed the earlier opportunity.

I find that EventHandler<T> is a great feature of the framework that is underutilised.

Most C# developers I come across still define a custom event handler delegate when they are defining custom events, which is simply not necessary anymore.

Instead of:

public delegate void MyCustomEventHandler(object sender, MyCustomEventArgs e);

public class MyCustomEventClass 
{
    public event MyCustomEventHandler MyCustomEvent;
}

you can go:

public class MyCustomEventClass 
{
    public event EventHandler<MyCustomEventArgs> MyCustomEvent;
}

which is a lot more concise, plus you don't get into the dilemma of whether to put the delegate in the .cs file for the class that contains the event, or the EventArgs derived class.


Here's a link to a snippet that makes it easy to create a custom EventArgs classes and an event that uses it: stackoverflow.com/questions/1157072/… - Ryan Lundy
97
[+20] [2010-04-21 15:41:05] ntziolis

What about IObservable?

Pretty much everybody knows IEnumerable [1] but their mathematical dual seems to be unknown IObservable [2]. Maybe because its new in .NET 4.

What it does is instead of pulling the information (like an enumerable) it pushes information to the subscriber(s) of the observerable.

Together with the Rx extensions [3] it will change how we deal with events. Just to illustrate how powerful it is check a very short example here [4].

[1] http://msdn.microsoft.com/en-us/library/9eekhta0.aspx
[2] http://msdn.microsoft.com/en-us/library/dd990377.aspx
[3] http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx
[4] http://channel9.msdn.com/posts/J.Van.Gogh/Writing-your-first-Rx-Application/

98
[+20] [2010-05-25 14:09:06] Thomas Levesque

OK, it may seem obvious, but I want to mention the Object.Equals method (the static one, with two arguments).

I'm pretty sure many people don't even know about it, or forget it's there, yet it can really help in some cases. For instance, when you want to compare two objects for equality, not knowing if they're null. How many times did you write something like that :

if ((x == y) || ((x != null && y != null) && x.Equals(y)))
{
    ...
}

When you can just write :

if (Object.Equals(x, y))
{
    ...
}

(Object.Equals is actually implemented exactly like in the first code sample)


99
[+20] [2010-06-30 09:24:46] Dan
string.Empty

I know it's not fantastical (ludicrously odd), but I use it all the time instead of "".

And it's pretty well hidden until someone tells you it's there.


Isn't "" shorter than string.Empty? - Arnis Lapsa
(2) @Arnis: string.Empty is more 'correct'. For reference though, .Empty isn't exactly a sparsely used value, most value types implement it, and Microsoft's guidelines encourage it's use (and indeed, static versions of common values, MinValue and MaxValue being two other common values). It can prevent unnecessary creation of duplicate value types when the same instance can be used (immutable value types). - Matthew Scharley
(4) @Arnos: It is not about beying short; it is about maintainability: understanding the meaning of something 2 months after you wrote some code. In stead of wondering where "" actually meant " " (and forgotting a space) or an empty string. String.Empty is much clearer. This holds for the .Empty pattern in general: you see it in many more types. - Jeroen Wiert Pluimers
(3) Not exactly hidden if you know a little bit about the framework. - Dave Van den Eynde
(3) This is one of things you get religious arguments about: string.Empty vs "" - personally I find the latter much easier to read, and it makes no different to the compiled code. - Keith
(2) As close to hidden as anything with signs pointing to it. For instance, StyleCop will tell you to use it: Warning 2 SA1122: Use string.Empty rather than "". - Task
I always found it a bit weird to be able to do typename.property in C# - bobobobo
bobobobo: static properties weird? - Dave Van den Eynde
(3) I find blogs.msdn.com/b/ericlippert/archive/2009/09/28/… to be of interest. It points out a case where "" and string.Empty will not have the same behavior during == comparisons. - Brian
(1) @bobobobo: I always use the upper case type names if accessing a type property or method: String.Empty instead of string.Empty or Double.Parse("1") instead of double.Parse("1"). I know it makes no difference for .net but it is more for myself to express that I use a value type (or string) like an object. In Java double and Double is not the same which is a little more consistent as in .net but I like the .net value type and string handling more. I got fooled more than once in Java by doing String a = "1"; String b = "1"; if(a == b) {...}; - Jürgen Steinblock
(3) String.Empty is .NET, not C#. It is accessible from any syntax on the .NET framework. - John K
@Jeroen Pluimers - That's exactly why I use it - Dan
Where is the study that shows the statistically higher error rate in apps that use "" instead of string.Empty? They produce the same IL, one is shorter and requires a lot less typing. The suggestion that it is possible to insert a space between those double quotes is fanciful. If you have a reason for using a string consisting of 1 or more spaces you would obviously declare it as a const or readonly to avoid having magic values in your code. - David Clarke
100
[+19] [2008-08-20 15:00:30] John Sheehan

I see a lot of people replicate the functionality of Nullable<T>.GetValueOrDefault(T).


In my opinion, ?? is cleaner in most cases, at least for primitive types (a ?? 0 instead of a.GetValueOrDefault()). The added burden of supplying the actual default value vanishes when you actually want another value. - OregonGhost
@OregonGhost: GetValueOrDefault (with or without a default value supplied) is about 33% faster than ??, although in truth, you won't notice a difference unless you do millions of iterations. - P Daddy
(1) @P Daddy: I tried to benchmark myself: GetValueOrDefault seems only to be 33% faster in Debug builds. In Release builds both are about the same. - helium
(1) I do this: var x = Nullable<X> ?? MyPreferedDefaultValue; - Jerry Nixon
101
[+19] [2009-01-01 16:10:01] Mark Cidade

C# 3.0's LINQ query comprehensions are full-blown monadic comprehensions a la Haskell (in fact they were designed by one of Haskell's designers). They will work for any generic type that follows the "LINQ pattern" and allows you to write in a pure monadic functional style, which means that all of your variables are immutable (as if the only variables you used were IDisposables and IEnumerables in using and foreach statements). This is helpful for keeping variable declarations close to where they're used and making sure that all side-effects are explicitly declared, if there are any at all.

 interface IFoo<T>
  { T Bar {get;}
  }

 class MyFoo<T> : IFoo<T> 
  { public MyFoo(T t) {Bar = t;}
    public T Bar {get; private set;} 
  }

 static class Foo 
  { public static IFoo<T> ToFoo<T>(this T t) {return new MyFoo<T>(t);}

    public static void Do<T>(this T t, Action<T> a) { a(t);}

    public static IFoo<U> Select<T,U>(this IFoo<T> foo, Func<T,U> f) 
     { return f(foo.Bar).ToFoo();
     }
  }

 /* ... */

 using (var file = File.OpenRead("objc.h"))
 { var x = from f in file.ToFoo()
           let s = new Scanner(f)
           let p = new Parser {scanner = s}
           select p.Parse();

   x.Do(p => 
    { /* drop into imperative code to handle file 
         in Foo monad if necessary */      
    });

 }

102
[+19] [2010-06-22 12:55:40] Steve Dunn

Not really hidden, but useful. When you've got an enum with flags, you can use shift-left to make things clearer. e.g.

[Flags]
public enum ErrorTypes {
    None              = 0,
    MissingPassword   = 1 << 0,
    MissingUsername   = 1 << 1,
    PasswordIncorrect = 1 << 2 
}

(2) Can you explain this? Not sure I follow how this works or what it does - Dan
(2) It's just shifting the bits in the binary representation of the number, 0001 << 1 becomes 0010, 0001 << 2 becomes 0100, 0001 << 3 becomes 1000 - CaffGeek
Nice one. @burnt_hand it's the shift operator msdn.microsoft.com/en-us/library/aa691377%28v=VS.71%29.aspx. (shifts left-hand value left by the right-hand number of bits) - Julien N
(1) (8 bit representation for brevity) 0000 0001 shifted one place left is 0000 00010 which is 2. It's a nice trick but I'm not sure it's clearer than = 1, = 2, = 4 etc unless you know bit shifting. It makes sure the reader has some CS experience though :) - Chris S
(5) Interesting, but anyone who doesn't immediately recognize the pattern 0,1,2,4,8...16384,32768... probably shouldn't be reading the code, and almost certainly won't know that 1 << 2 == 4. - ScottS
(5) FlagsAttribute alone should make one realize that enum is a bit field. IMO shifting bits in enum definition is not for readability but for lazies, who don't bother remembering the power of two values ;) - Aoi Karasu
(19) @AOIKarasu- C# itself is for lazies who can't be bothered with lower level languages. Lower level languages are for lazies who can't be bother with Assembler. Assembler is for lazies who can't be bothered typing in binary. Typing is for lazies who can't be bothered etching tiny dots on a hard disk.Hard disks are for lazies who can't be bothered with punch cards. Punch cards are for lazies who can't be bothered scribing on paper. Paper is for lazies who can't be bothered etching on stone tablets. I'm in all of those varieties of lazy! :) Bit 9 is still easer to read as 1 << 9 than 512. YMMV! - Steve Dunn
(2) You're leaving one out, since 1 << 1 is 2, your first flag should be 1 << 0. - Dave Van den Eynde
@Chad - Perfect explanation. I knew of pushing bits around, but not applying that to Flags. Mine always were the 0,1,2,4,8 style. - Dan
Is this really clearer than 0, 1, 2, 4, 8, 16...? - Ryan Lundy
(1) The "You're leaving one out, since 1 << 1 is 2" comment and subsequent fix points out an irony of human thought. While the shifting approach is in theory cleaner and safer because the computer does the math, it is in practice more error prone: the off-by-one error can be hard to spot, but an incorrect power of two sequence is easy. - Edward Brey
103
[+18] [2009-04-17 07:09:13] Peter Lillevold

My favorite attribute: InternalsVisibleTo [1]

At assembly level you can declare that another assembly can see your internals. For testing purposes this is absolutely wonderful.

Stick this in your AssemblyInfo.cs or equivalent and your test assembly get full access to all the internal stuff that requires testing.

[assembly: InternalsVisibleTo("MyLibrary.Test, PublicKey=0024...5c042cb")]

As you can see, the test assembly must have a strong name [2] to gain the trust of the assembly under test.

Available in .Net Framework 2.0+, Compact Framework 2.0+ and XNA Framework 1.0+.

[1] http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx
[2] http://msdn.microsoft.com/en-us/library/xc31ft41.aspx

(3) Yeah, great for test assemblies... And only test assemblies. Right? ;) - JohannesH
@JohannesH - Yes, I would agree. There is a good reason for having the internal keyword, and that is to keep things internal :) - Peter Lillevold
104
[+17] [2008-08-28 16:17:15] Nathan Lee

I love using the @ character for SQL queries. It keeps the sql nice and formatted and without having to surround each line with a string delimiter.

string sql = @"SELECT firstname, lastname, email
               FROM users
               WHERE username = @username AND password = @password";

I use '@' all the time, but I never thought of spanning multiple lines! :-P - Christopher Bennage
(4) One minor gripe with this (in this scenario) is that the spaces used for indenting and the newline characters end up in the string. Not generally a problem but one to be aware of. - BlackWasp
(17) Another problem is that you're writing SQL in code :( - Matt Grande
(1) I agree, its often not a good idea to write raw SQL like this, but its not always possible to get away from SQL code. Besides, it is just an example. - Nathan Lee
(2) The SQL uses parameters. Apart from the SQL itself being hardcoded, I don't see any problems. - Dave Van den Eynde
Agree with Dave. Why it is "always" bad to write sql in code? What about hardcode complete statements. I see no problems too. - Daniel Bişar
105
[+17] [2008-09-01 13:21:10] Jakub Šturc

The extern alias [1] keyword to reference two versions of assemblies that have the same fully-qualified type names.

[1] http://msdn.microsoft.com/en-us/library/ms173212.aspx

106
[+17] [2009-09-16 19:38:58] Keith Adler

You can limit the life and thus scope of variables by using { } brackets.

{
    string test2 = "3";
    Console.Write(test2);
}

Console.Write(test2); //compile error

test2 only lives within the brackets.


(2) This is true of C++ too. - ChrisF
True of any language with lexical scoping no? - Phillip Cloud
hmmm...Is this a hidden feature?? - Kai
107
[+17] [2009-11-12 19:43:24] user1228

Need to return an empty IEnumerable?

public IEnumerable<T> GetEnumerator(){
  yield break;
}

(9) Already in the BCL System.Linq.Enumerable.Empty<T>() - chakrit
(2) @chak Which is a wrapper around return new T[0];. There are many ways to do this. This is but just one. But it is an interesting one... - user1228
(5) This one is a little opaque for my tastes, I prefer chakrit's solution. - Alex Baranosky
Actually, it's a wrapper around a static instance of T[], so new T[0] is only called once per type. - phoog
@Alex: I'd prefer yield break in a generator function (i.e. which also yield returns) I'd use Enumerable.Empty everywhere else - sehe
108
[+16] [2008-11-19 16:28:25] Tor Haugen

You can use any Unicode character in C# names, for example:

public class MyClass
{
    public string Hårføner()
    {
        return "Yes, it works!";
    }
}

You can even use Unicode escapes. This one is equivalent to the above:

public class MyClass
{
    public string H\u00e5rføner()
    {
        return "Yes, it (still) works!";
    }
}

To anyone outside the english-speaking world, it's actually a giant leap towards language-agnostic computing. To us (to me, at least), it's actually somewhat quaint and old-fashioned to have to stick to the 26 letters of the english alphabet. A bit like 8.3 file names, you know. - Tor Haugen
(4) Hmm, yes, let's mix English BCL identifiers and keywords with non-English identifiers. Now people from other countries can't use your code anymore without Intellisense :P ;) No. It's only consequent to be able to use any character, but there's no real benefit to it. - OregonGhost
(1) Although some might find this useful I think it should be avoided in our industry since we will often have several nationalities involved in a project. Also as OregonGhost mentiones it will go against existing naming in BCL and 3rd party libraries. I'm currently working on a project which didn't use english naming and we are now suffering from confusing names as well as the inability to hand over our code to our indian testers without extensive documentation and transcription of member names. Remember that code should be readable by humans... This includes humans of other nationalities. - JohannesH
+1 - I'm using the unicode Pi and Tau symbols as members in my Math class - makes code much nicer to read! float area = Math.π * (radius * radius). What I'd really like to do is define an extension method called ² so I can type float area = Math.π * radius.²(); - MattDavey
109
[+16] [2008-12-16 06:07:30] Rinat Abdullin

Ability to use LINQ Expressions to perform strongly-typed reflection:

static void Main(string[] args)
{
  var domain = "matrix";
  Check(() => domain);
  Console.ReadLine();
}

static void Check<T>(Expression<Func<T>> expr)
{
  var body = ((MemberExpression)expr.Body);
  Console.WriteLine("Name is: {0}", body.Member.Name);
  Console.WriteLine("Value is: {0}", ((FieldInfo)body.Member)
   .GetValue(((ConstantExpression)body.Expression).Value));
}

// output:
// Name is: 'domain'
// Value is: 'matrix'

More details are available at How to Find Out Variable or Parameter Name in C#? [1]

[1] http://rabdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html

+1 You can also do this with anonymous types. - MattDavey
110
[+16] [2010-02-14 18:52:49] A1exandr Belan

You can store colors in Enum.

public enum MyEnumColors : uint
{
    Normal          = 0xFF9F9F9F,
    Active          = 0xFF8EA98A,
    Error           = 0xFFFF0000
}

(3) Yes, but what for? Why not create strongly-typed static class attributes instead? Might just as well abuse strings to store arbitrary blobs of data, instead of using classes, as was done often in BASIC. - Konrad Rudolph
(4) I think FFire is trying to draw attention to the fact that you can specify the base type (in this case uint) for an enum - sehe
111
[+15] [2008-08-12 17:29:29] Lars Mæhlum

I have often come across the need to have a generic parameter-object persisted into the viewstate in a base class.

public abstract class BaseListControl<ListType,KeyType,ParameterType>
                 : UserControl 
                 where ListType : BaseListType
                 && ParameterType : BaseParameterType, new
{

    private const string viewStateFilterKey = "FilterKey";

    protected ParameterType Filters
    {
        get
        {
            if (ViewState[viewStateFilterKey] == null)
                ViewState[viewStateFilterKey]= new ParameterType();

            return ViewState[viewStateFilterKey] as ParameterType;
        }
        set
        {
            ViewState[viewStateFilterKey] = value;
        }
    }

}

Usage:

private void SomeEventHappened(object sender, EventArgs e)
{
    Filters.SomeValue = SomeControl.SelectedValue;
}

private void TimeToFetchSomeData()
{
    GridView.DataSource = Repository.GetList(Filters);
}

This little trick with the "where ParameterType : BaseParameterType, new" is what makes it really work.

With this property in my baseclass, I can automate handling of paging, setting filter values to filter a gridview, make sorting really easy, etc.

I am really just saying that generics can be an enormously powerful beast in the wrong hands.


Maybe I'm being daft, but I'm not sure I understand the code. Could you post a more complete example? - ilivewithian
(1) Its pretty simple actually. If you have a GridView with a couple of DropDownLists to filter out content, you just put the values into your filter object that is persisted between postbacks, and send it as a parameter to the method that fetches data from the DB. You would just implement your UserControl inheriting from BaseListControl, and the base takes care of persisting "state" between postbacks. - Lars Mæhlum
(1) what do you mean "little trick"? Are you referring to the fact that you can't create a parameterised type inside a generic unless the generic constraints contains a "new" clause? - Andy Dent
No, the little trick is constraining to BaseParameterType. A bit of a typo :\ - Lars Mæhlum
112
[+15] [2008-08-22 03:55:51] Martin Clarke

How about the FlagsAttribute [1] on an enumeration? It allows you to perform bitwise operations... took me forever to find out how to do bitwise operations in .NET nicely.

[1] http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx

(5) I think you can do bitwise operations on any enum, flags only affect the ToString() method - Olmo
(10) This is actually pretty dangerous - it doesn't have any effect on the values assigned - it's purely a marker attribute to indicate your intention, so if you don't explicitly declare your enum values as powers of two then you will think you have a bitwise enum, but you won't really... - user6586
(1) You cannot use the Enum.HasFlag(...) method unless the Enum you're referencing has the FlagsAttribute attribute. - cwharris
113
[+15] [2009-06-26 16:13:06] Mike

You can add and remove delegates with less typing.

Usual way:

handler += new EventHandler(func);

Less typing way:

handler += func;

(4) Saw that all the time... just make my hand itch :) Also, if you type += in VS and then [TAB][TAB] to generate an event handler, the delegate type is still inserted... kinda annoying. - chakrit
@sr pt: No it is not a resharper functionality. It is a default function in Visual studio (I even believe it is in there since 2005). Visual studio has more of these auto complete snippets. - Gertjan
(1) @Aneves: Resharper lets you easily remove this extra bit of fluff though. - Matthew Scharley
114
[+15] [2010-03-16 15:37:04] Edison Chuang

Using "~" operator with FlagAttribute and enum
Sometime we would use Flag attribute with enum to perform bitwise manipulation on the enumeration.

 [Flags]
 public enum Colors
 {
    None  = 0,
    Red   = 1,
    Blue  = 2,
    White = 4,
    Black = 8,
    Green = 16,
    All   = 31 //It seems pretty bad...
 }

Notice that, the value of option "All" which in enum is quite strange.
Instead of that we can use "~" operator with flagged enum.

 [Flags]
 public enum Colors
 {
    None  = 0,
    Red   = 1,
    Blue  = 2,
    White = 4,
    Black = 8,
    Green = 16,
    All   = ~0 //much better now. that mean 0xffffffff in default.
 }

it must be 32 i think not 31, what you say? - Mubashar
(3) Remember that it is a flagged enum. So in this case "All" equal to (Red & Blue & White & Black & Green) then it would also equal to (00001 & 00010 & 00100 & 01000 & 10000) and equal to 11111 and equal to 31 as well. The number 32 should be 100000 but 11111. - Edison Chuang
(2) I prefer spelling it out All = Red | Blue | White | Black | Green and e.g. Dark = Blue | Black, Light = All & ~Dark - sehe
115
[+15] [2010-06-29 06:12:32] Incognito

Also useful, but not commonly used : Constrained Execution Regions [1].

A quote from BCL Team blog :

Constrained execution regions (CER's) exist to help a developer write her code to maintain consistency. The CLR doesn't guarantee that the developer's code is correct, but the CLR does hoist all of the runtime-induced failure points (ie, async exceptions) to either before the code runs, or after it has completed. Combined with constraints on what the developer can put in a CER, these are a useful way of making strong guarantees about whether your code will execute. CER's are eagerly prepared, meaning that when we see one, we will eagerly JIT any code found in its statically-discoverable call graph. If the CLR's host cares about stack overflow, we'll probe for some amount of stack space as well (though perhaps not enough stack space for any arbitrary method*). We also delay thread aborts until the CER has finished running.

It can be useful when making edits to more than one field of a data structure in an atomic fashion. So it helps to have transactions on objects.

Also CriticalFinalizerObject [2] seems to be hidden(at least who are not writing unsafe code). A CriticalFinalizerObject guarantees that garbage collection will execute the finalizer. Upon allocation, the finalizer and its call graph are prepared in advance.

[1] http://msdn.microsoft.com/en-us/library/ms228973.aspx
[2] http://msdn.microsoft.com/en-us/library/system.runtime.constrainedexecution.criticalfinalizerobject.aspx

Hmm... could that make aborting threads safe if they were written for it? - devios1
116
[+15] [2010-06-30 18:09:05] Incognito

fixed [1] statement

This statement prevents the garbage collector from relocating a movable variable. Fixed can also be used to create fixed size buffers.

The fixed statement sets a pointer to a managed variable and "pins" that variable during the execution of statement.

stackalloc [2]

The stackalloc allocates a block of memory on the stack.

[1] http://msdn.microsoft.com/en-us/library/f58wzh21(VS.80).aspx
[2] http://msdn.microsoft.com/en-us/library/cx9s2sy4(VS.71).aspx

(4) I think this should include an example of why/how this can be useful - Neil N
(1) @Neil You can follow the links in the answer. There you can see some examples and more details on remarks section. Tell me if that will not be satisfying I'll update the answer with example code. - Incognito
(1) Code formatting and links don't mix well; it's not immediately obvious that the keywords are links as well. But of course, the links are relevant, once you find them :-) - Zano
@Zano code formating is removed. Hope it is easy to notice links now. - Incognito
What has not been mentioned so far, for people that started learning programming with a GC: stack allocation is basically just an incrementation of the stack pointer and is therefore, well, let's call it "really fast". ;-) since there will be a stack allocated for the running function, anyways, i guess that the stackalloc memory is just added when doing that allocation, therefore making it a no-op without any runtime penalties at all. That's just my guess, though. - Daniel Albuschat
IMO, only including links to explain somthing can limit the usefulness of your answer, as the links may eventually become broken. - Mr.Mindor
117
[+14] [2008-08-29 21:28:19] Andrew Burns

ConditionalAttribute [1]

Allows you to tell the compiler to omit the call to the method marked with the attribute under certain conditions (#define).

The fact that the method call is omitted also means that its parameters are not evaluated. This is very handy and it's what allows you to call expensive validation functions in Debug.Assert() and not worry about them slowing down your release build.

[1] http://msdn.microsoft.com/en-us/library/aa664622(VS.71).aspx

118
[+14] [2008-09-29 16:34:13] Mihai Lazar

One feature that I only learned about here on Stack Overflow was the ability to set an attribute on the return parameter.

[AttributeUsage( AttributeTargets.ReturnValue )]
public class CuriosityAttribute:Attribute
{
}

public class Bar
{
    [return: Curiosity]
    public Bar ReturnANewBar()
    {
        return new Bar();
    }
}

This was truly a hidden feature for me :-)


(3) It applies Curiosity as an attribute to the returned instance. - Mihai Lazar
You can also use attributes on method parameters (common in MVC) eg. public ActionResult Register([Bind(Prefix = "Person")] string name) - Dan Diplo
119
[+14] [2008-10-03 05:57:04] tsilb

Labeling my endregions...

#region stuff1
 #region stuff1a
 //...
 #endregion stuff1a
#endregion stuff1

120
[+14] [2009-09-12 19:26:18] codymanix

When defining custom attributes you can use them with [MyAttAttribute] or with [MyAtt]. When classes exist for both writings, then a compilation error occures.

The @ special character can be used to distinguish between them:

[AttributeUsage(AttributeTargets.All)]
public class X: Attribute
{}

[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}

[X]      // Error: ambiguity
class Class1 {}

[XAttribute]   // Refers to XAttribute
class Class2 {}

[@X]      // Refers to X
class Class3 {}

[@XAttribute]   // Refers to XAttribute
class Class4 {}

Of course, the best solution is to fix one or both names so they don't clash in the first place. But this is good to know in case of dealing with third-party libraries that did it wrong, and that you can't fix. - Ryan Lundy
121
[+14] [2010-04-22 07:40:51] Jehof

When a class implements INotifyPropertyChanged [1] and you want to inform the binding system (WPF, Silverlight, etc.) that multiple bound properties of an object (ViewModel) have changed you can raise the PropertyChanged-Event with null or String.Empty.

This is documented in MSDN, but code examples and articles often don´t explain this possibility. I found it very useful.

public class BoundObject : INotifyPropertyChanged {

    private int _value;
    private string _text;

    public event PropertyChangedEventHandler PropertyChanged;

    public int Value {
        get {
            return _value;
        }
        set {
            if (_value != value) {
                _value = value;
                OnPropertyChanged("Value");
            }
        }
    }

    public string Text {
        get {
            return _text;
        }
        set {
            if (_text != value) {
                _text = value;
                OnPropertyChanged("Text");
            }
        }
    }

    public void Init(){
        _text = "InitialValue";
        _value = 1;
        OnPropertyChanged(string.Empty);
    }

    public void Reset() {
        _text = "DefaultValue";
        _value = 0;
        OnPropertyChanged(string.Empty);
    }

    private void OnPropertyChanged(string propertyName) {
        PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);

        if (PropertyChanged != null) {
            PropertyChanged(this, e);
        }
    }
}
[1] http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged%28v=VS.80%29.aspx

122
[+14] [2010-07-03 17:31:40] Ozan

You can put several attributes in one pair of square brackets:

    [OperationContract, ServiceKnownType(typeof(Prism)), ServiceKnownType(typeof(Cuboid))]
    Shape GetShape();

(1) I hate it when CodeAnalysis puts it SuppressMessage attribute inside other attributes... For me I like to allign all attributes. - riezebosch
123
[+13] [2008-08-13 18:47:41] t3rse

Lambda Expressions

Func<int, int, int> add = (a, b) => (a + b);

Obscure String Formats

Console.WriteLine("{0:D10}", 2); // 0000000002

Dictionary<string, string> dict = new Dictionary<string, string> { 
    {"David", "C#"}, 
    {"Johann", "Perl"}, 
    {"Morgan", "Python"}
};

Console.WriteLine( "{0,10} {1, 10}", "Programmer", "Language" );

Console.WriteLine( "-".PadRight( 21, '-' ) );

foreach (string key in dict.Keys)
{
    Console.WriteLine( "{0, 10} {1, 10}", key, dict[key] );             
}

Lambda Expressions are explained more fully here: developer.com/net/csharp/article.php/3598381 and here: msdn.microsoft.com/en-us/library/bb397687.aspx - Ogre Psalm33
124
[+13] [2008-08-15 14:51:42] AlexCuse

I didn't start to really appreciate the "using" blocks until recently. They make things so much more tidy :)


125
[+13] [2008-11-19 16:58:38] MysticSlayer

What about using this:

#if DEBUG
            Console.Write("Debugging");
#else
            Console.Write("Final");
#endif

When you have your solution compiled with DEBUG defined it will output "Debugging".

If your compile is set to Release it will write "Final".


126
[+13] [2009-06-05 18:43:55] Andrew Lavers

FlagsAttribute, a small but nice feature [1] when using enum to make a bitmasks:

[Flags]
public enum ConfigOptions
{
    None    = 0,
    A       = 1 << 0,
    B       = 1 << 1,
    Both    = A | B
}

Console.WriteLine( ConfigOptions.A.ToString() );
Console.WriteLine( ConfigOptions.Both.ToString() );
// Will print:
// A
// A, B
[1] http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx

(1) +1 for explicitely showcasing the ToString() behaviour for combined flags - sehe
127
[+13] [2009-07-30 04:23:58] Brian Surowiec

I'm becoming a big fan of extension methods since they can add much wanted functionality to existing code or code you can't edit. One of my favorites I add in to everything I do now is for string.IsNullOrEmpty()

public static class Strings
{
    public static bool IsNullOrEmpty(this string value)
    {
        return string.IsNullOrEmpty(value);
    }
}

This lets you shorten your code a bit like this

var input = Console.ReadLine();
if (input.IsNullOrEmpty())
{
    Console.WriteLine("try again");
}

(1) I hope you realize that this example is impossible, because IsNullOrEmpty is already a member of the type string. Extension methods can not have the same name as any member (static or non-static) of that type, which it extends. - John Leidegren
(3) I'm using this in 2 projects for work right now plus numerous personal projects. I put the IsNullOrEmpty method inside of a class called Strings along with my other extension methods for the string class. I haven't had any issue with the compiler telling me the method name is invalid and have been using it in my code for 3 or 4 months now. - Brian Surowiec
(3) @John: I tried Brian's code, it works. - redtuna
@Brian: What happens, when input is null? I´m not so familiar with extension methods. - Jehof
@John: IsNullOrEmpty is a static method, so it doesn't interfere with dynamic methods. @Jehof: It works because an extension method is just some syntax sugar around a static method call. DynamicFoo.MyMethod() is run as if you wrote MyMethod(DynamicFoo), passing null to a method is perfectly okay. - Jauco
It's nice but maybe confusing, no ? When you read code you don't know it's an extension method. And at first sight it looks strange to do input.IsNullOrEmpty() - Julien N
(2) @John I think it works because the original IsNullOrEmpty take one parameter and not this one. So it's just overloading. - Julien N
(1) @Julien N - Ah, right you are. I do write this kind of code, but I just call it IsEmpty and I have another IsNonEmpty, I personally don't like the ! operator much. - John Leidegren
128
[+13] [2009-11-20 14:57:05] thr

Type-inference for factory methods

I don't know if this has been posted already (I scanned the first post, couldn't find it).

This is best shown with an example, assuming you have this class (to simulate a tuple), in in an attempt to demonstrate all the language features that make this possible I will go through it step by step.

public class Tuple<V1, V2> : Tuple
{
    public readonly V1 v1;
    public readonly V2 v2;

    public Tuple(V1 v1, V2 v2)
    {
      this.v1 = v1;
      this.v2 = v2;
    }
}

Everyone knows how to create an instance of it, such as:

Tuple<int, string> tup = new Tuple<int, string>(1, "Hello, World!");

Not exactly rocket science, now we can of course change the type declaration of the variable to var, like this:

var tup = new Tuple<int, string>(1, "Hello, World!");

Still well known, to digress a bit here's a static method with type parameters, which everyone should be familiar with:

public static void Create<T1, T2>()
{
    // stuff
}

Calling it is, again common knowledge, done like this:

Create<float, double>();

What most people don't know is that if the arguments to the generic method contains all the types it requires they can be inferred, for example:

public static void Create<T1, T2>(T1 a, T2 b)
{
    // stuff
}

These two calls are identical:

Create<float, string>(1.0f, "test");
Create(1.0f, "test");

Since T1 and T2 is inferred from the arguments you passed. Combining this knowledge with the var keyword, we can by adding a second static class with a static method, such as:

public abstract class Tuple
{
    public static Tuple<V1, V2> Create<V1, V2>(V1 v1, V2 v2)
    {
        return new Tuple<V1, V2>(v1, v2);
    }
}

Achieve this effect:

var tup = Tuple.Create(1, "Hello, World!");

This means that the types of the: variable "tup", the type-parameters of "Create" and the return value of "Create" are all inferred from the types you pass as arguments to Create

The full code looks something like this:

public abstract class Tuple
{
    public static Tuple<V1, V2> Create<V1, V2>(V1 v1, V2 v2)
    {
        return new Tuple<V1, V2>(v1, v2);
    }
}

public class Tuple<V1, V2> : Tuple
{
    public readonly V1 v1;
    public readonly V2 v2;

    public Tuple(V1 v1, V2 v2)
    {
        this.v1 = v1;
        this.v2 = v2;
    }
}

// Example usage:
var tup = Tuple.Create(1, "test");

Which gives you fully type inferred factory methods everywhere!


129
[+13] [2010-01-08 10:03:33] cllpse

Easier-on-the-eyes / condensed ORM-mapping using LINQ

Consider this table:

[MessageId] INT,
[MessageText] NVARCHAR(MAX)
[MessageDate] DATETIME

... And this structure:

struct Message
{
    Int32 Id;
    String Text;
    DateTime Date;
}



Instead of doing something along the lines of:

List<Message> messages = new List<Message>();

foreach (row in DataTable.Rows)
{
    var message = new Message
    {
        Id = Convert.ToInt32(row["MessageId"]),
        Text = Convert.ToString(row["MessageText"]),
        Date = Convert.ToDateTime(row["MessageDate"])
    };

    messages.Add(message);
}

You can use LINQ and do the same thing with fewer lines of code, and in my opinion; more style. Like so:

var messages = DataTable.AsEnumerable().Select(r => new Message
{
    Id = Convert.ToInt32(r["MessageId"]),
    Text = Convert.ToString(r["MessageText"]),
    Date = Convert.ToDateTime(r["MessageDate"])
}).ToList();

This approach can be nested, just like loops can.


(2) It's an interesting approach, but I'm not convinced that it's easier on the eyes. It's definitely not easier to understand for the average programmer, in my opinion. - Ryan Lundy
(10) +1 for greatly improving the readability. I think the new code is much easier on the eyes. Although today the average C# programmer is still programming procedurally, that will change quickly. I've found that when you show most procedural programmers the LINQ version they understand immediately and say something like "wow!" and want to know how they can use it themselves. - Ray Burns
(1) @roosteronacid: I hope you don't mind that I simplified your LINQ code slightly to make it even more readable. If it's a problem, just change it back. - Ray Burns
@Ray Burns: thanks for the revision. It's now even more easy on the eyes :) - cllpse
(3) You can even use the Field<T>(name) extensions: r.Field<int>("MessageId") (I wish I didn't have to know that) - kͩeͣmͮpͥ ͩ
130
[+12] [2008-09-18 06:08:15] Alex Lyman

Falling through switch-cases can be achieved by having no code in a case (see case 0), or using the special goto case (see case 1) or goto default (see case 2) forms:

switch (/*...*/) {
    case 0: // shares the exact same code as case 1
    case 1:
        // do something
        goto case 2;
    case 2:
        // do something else
        goto default;
    default:
        // do something entirely different
        break;
}

(1) Note that "goto case" is discouraged in this article: msdn.microsoft.com/en-us/vcsharp/aa336815.aspx - J c
(1) I'd be one to suggest that any use of 'goto' is discouraged in general -- but that doesn't mean that it isn't useful. - Alex Lyman
(10) I think in a switch is only place a goto is acceptable. - Matt Grande
(1) I think I would be very upset if I encountered code like this and had to debug or maintain it... - Richard Ev
@Richard E: I think that's why its well-hidden, really. Only power users really read ECMA-334, so its rather likely that its only used sparingly. - Alex Lyman
case 2: default: break; will return the same thing even without the goto default; - Martin Ongtangco
(1) @Martin Ongtangco: Only if case 2's "// do something else" is empty. - Alex Lyman
131
[+12] [2008-11-04 23:30:41] Cohen

Something I missed for a long time: you can compare strings with

"string".equals("String", StringComparison.InvariantCultureIgnoreCase)

instead of doing:

"string".ToLower() == "String".ToLower();

(2) I know this should be the correct approach, but I'm annoyed by verbosity of the enum itself. - dbkk
(7) Actualy, StringComparison.OrdinalIgnoreCase should be used in many case. - François
(4) also microsoft has optimized for upper case comparisons so ToUppper would be better on the old way. - Maslow
This is the correct way to compare strings. - BrainSlugs83
132
[+12] [2009-11-30 17:41:12] Paul Ruane

A couple I can think of:

[field: NonSerialized()]
public EventHandler event SomeEvent;

This prevents the event from being serialised. The 'field:' indicates that the attribute should be applied to the event's backing field.

Another little known feature is overriding the add/remove event handlers:

public event EventHandler SomeEvent
{
    add
    {
        // ...
    }

    remove
    {
        // ...
    }
}

133
[+11] [2008-08-14 10:59:21] Duncan Smart

I love the fact that I can use LINQ to objects on plain old .NET 2.0 (i.e. without requiring .NET 3.5 to be installed everywhere). All you need is an implementation of all the query operator Extension methods - see LINQBridge [1]

[1] http://www.albahari.com/nutshell/linqbridge.html

134
[+11] [2008-09-16 13:56:08] Benjol
  1. I can't comment yet, but note that by default Visual Studio 2008 automatically steps over properties, so the DebuggerStepThrough attribute is no longer needed in that case.

  2. Also, I haven't noticed anyone showing how to declare a parameter-less lambda (useful for implementing Action<>)

    () => DoSomething(x);

You should also read up on closures - I'm not clever enough to explain them properly. But basically it means that the compiler does clever stuff so that the x in that line of code will still work even if it goes 'out of scope' after creating the lambda.

  1. I also discovered recently that you can pretend to ignore a lambda parameter:

    (e, _) => DoSomething(e)

It's not really ignoring it, it's just that _ is a valid identifier. So you couldn't ignore both of the parameters like that, but I think it is a kind of neat way to indicate that we don't care about that parameter (typically the EventArgs which is .Empty).


135
[+11] [2008-09-23 14:44:29] Flory

There are operators for performing implicit [1] and explicit [2] user-defined type conversion between the declared class and one or more arbitrary classes. The implicit operator effectively allows the simulation of overloading the assignement operator, which is possible in languages such as C++ but not C#.

It doesn't seem to be a feature one comes across very often, but it is in fact used in the LINQ to XML [3] (System.Xml.Linq) library, where you can implicitly convert strings to XName objects. Example:

XName tagName = "x:Name";

I discovered this feature in this article [4] about how to simulate multiple inheritance in C#.

[1] http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx
[2] http://msdn.microsoft.com/en-us/library/xhbhezf4.aspx
[3] http://en.wikipedia.org/wiki/Language_Integrated_Query#LINQ_to_XML
[4] http://www.codeproject.com/KB/architecture/smip.aspx

136
[+11] [2008-12-03 04:45:34] Phillip Ngan

The delegate syntax have evolved over successive versions of C#, but I still find them difficult to remember. Fortunately the Action<> and Func<> delegates are easy to remember.

For example:

  • Action<int> is a delegate method that takes a single int argument and returns void.
  • Func<int> is a delegate method that takes no arguments and returns an int.
  • Func<int, bool> is a delegate method that takes a single int argument and returns a bool.

These features were introduced in version 3.5 of the .NET framework.


Action<T> is available in .NET 2.0. It's a shame that Func isn't, because it would make using lambdas easier. - OregonGhost
A few of them: Action, Comparison, Converter, EventHandler, Func, Predicate (see stackoverflow.com/questions/319789/… ) - ANeves
137
[+11] [2009-03-06 11:49:20] tuinstoel

You can use generics to check (compile time) if a method argument implements two interfaces:

interface IPropA 
{
    string PropA { get; set; } 
}

interface IPropB 
{
    string PropB { get; set; }
}

class TestClass 
{
    void DoSomething<T>(T t) where T : IPropA, IPropB 
    {
        MessageBox.Show(t.PropA);
        MessageBox.Show(t.PropB);
    }
}

Same with an argument that is inherited from a base class and an interface.


In this case, would you need to do var a = (IPropA)t; var propa = a.PropA; Just in case the interface is explicitly implemented? - Mark
@Mark, I don't understand your question so I can't answer it. - tuinstoel
(1) @Mark: No, you don't have to cast it. The fact that t implements the given interfaces is known explicitly from the where (in fact, that is all that is known, other than that t is an object), so the cast is unnecessary. When t.PropA is accessed, it works exactly as if t were a non-generic parameter of type IPropA, and when t.PropB is accessed, it works exactly as if t were a non-generic parameter of type IPropB. - P Daddy
(1) @tuinstoel: +1! This is an excellent demonstration of functionality that's not possible without generics. - P Daddy
138
[+11] [2009-07-02 00:34:17] Wim Coenen

Extension methods can be called on null; this will not cause a NullReferenceException to be thrown.

Example application: you can define an alternative for ToString() called ToStringOrEmpty() which will return the empty string when called on null.


I was pretty geeked when I discovered this fact as it allows me to write much cleaner code in certain instances on my current project. - Kleinux
What's even better -- ToStringOrDefault(this object obj, object default) -- and ToStringOrEmpty(this object obj) { obj.ToStringOrDefault(String.Empty); } - BrainSlugs83
139
[+10] [2008-12-13 21:53:01] Binoj Antony

To call the base class constructor just put base() inline with the constructor.
To call the base class method you can just put base.MethodName() inside the derived class method

class ClassA 
{
  public ClassA(int a)
  {
    //Do something
  }

  public void Method1()
  {
     //Do Something
  }
}

class ClassB : ClassA
{
  public ClassB(int a) : base(a) // calling the base class constructor
  {
    //Do something
  }

  public void Method2()
  {
    base.Method1();               // calling the base class method
  }
}

Of course you can call the methods of the base class by just saying base.MethodName()


140
[+10] [2008-12-23 12:27:07] Moran Helman

TrueForAll Method of List<T> :

List<int> s = new List<int> { 6, 1, 2 };

bool a = s.TrueForAll(p => p > 0);

Linq: s.All(p => p > 0); - Daniel Bişar
141
[+10] [2009-05-08 15:35:04] nsantorello

One thing not many people know about are some of the C#-introduced preprocessor directives. You can use #error This is an error. to generate a compiler error and #warning This is a warning.

I usually use these when I'm developing with a top-down approach as a "todo" list. I'll #error Implement this function, or #warning Eventually implement this corner case as a reminder.


These are good but I recently discovered that #warning in Silverlight doesn't stop the build when Warnings as Errors is set, even though it should. - Jeff Yates
(2) Can't you just use TODO: comments in Visual Studio? dotnetperls.com/todo-comments-visual-studio - Dan Diplo
@DanDiplo Not everyone's using Visual Studio... - Jeroen Landheer
@DanDiplo you can. And you can also use #error and #warning. There is a time and a place for everything. Consider if you're using other preprocessor directives, and there happens to be a set that is either untested, or known to break things... you can put #errors and #warnings in those cases (counter-respectively), and you'll never see them unless someone tries to compile with improper settings; (ex: You're using PInvoke and the call doesn't work if you compile in 64-bit mode, use preprocessor directive to detect that you're compiling for any-CPU and include an #error.) - BrainSlugs83
142
[+10] [2009-06-19 13:08:28] Titian Cernicova-Dragomir

Not sure if this one got mentioned yet but the ThreadStatic attribute is a realy useful one. This makes a static field static just for the current thread.

[ThreadStatic]
private static int _ThreadStaticInteger;

You should not include an initializer because it only get executed once for the entire application, you're better off making the field nullable and checking if the value is null before you use it.

And one more thing for ASP.NET applications threads are reused so if you modify the value it could end up being used for another page request.

Still I have found this useful on several occasions. For example in creating a custom transaction class that:

using (DbTransaction tran = new DbTransaction())
{
    DoQuery("...");
    DoQuery("...");    
}

The DbTransaction constructor sets a ThreadStatic field to its self and resets it to null in the dispose method. DoQuery checks the static field and if != null uses the current transaction if not it defaults to something else. We avoid having to pass the transaction to each method plus it makes it easy to wrap other methods that were not originaly meant to be used with transaction inside a transaction ...

Just one use :)


143
[+10] [2009-06-30 08:55:57] Mark Seemann

The Or assignment operator is quite nice. You can write this:

x |= y

instead of this:

x = x | y

This is often practical if you have to a variable or property (x in the example) that starts out as false but you want to change it to the value of some other boolean variable/property only when that other value is true.


"starts out as false but you want to change it to the value of some other boolean variable/property only when that other value is true." this means "x=y" ^^ EDIT: didn't notice the huge necromancy i just performed. oh well. - Alex
144
[+10] [2009-09-09 11:14:47] jpierson

Nested classes can access private members of a outer class.

public class Outer
{
    private int Value { get; set; }

    public class Inner
    {
        protected void ModifyOuterMember(Outer outer, int value)
        {
            outer.Value = value;
        }
    }
}

And now together with the above feature you can also inherit from nested classes as if they were top level classes as shown below.

public class Cheater : Outer.Inner
{
    protected void MakeValue5(Outer outer)
    {
        ModifyOuterMember(outer, 5);
    }
}

These features allow for some interesting possibilities as far as providing access to particular members via somewhat hidden classes.


145
[+10] [2010-03-27 23:38:47] Velocoder

You can change rounding scheme using:

var value = -0.5;
var value2 = 0.5;
var value3 = 1.4;

Console.WriteLine( Math.Round(value, MidpointRounding.AwayFromZero) ); //out: -1
Console.WriteLine(Math.Round(value2, MidpointRounding.AwayFromZero)); //out: 1
Console.WriteLine(Math.Round(value3, MidpointRounding.ToEven)); //out: 1

146
[+9] [2008-08-19 16:07:50] John Asbeck

Preprocessor Directives can be nifty if you want different behavior between Debug and Release modes.

http://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx


Definitely. I have code in a project I'm working on that bypasses the login screen in Debug mode. Makes every test run that much quicker! - lc.
147
[+9] [2008-09-23 14:36:02] axel_c
System.Diagnostics.Debug.Assert (false);

will trigger a popup and allow you to attach a debugger to a running .NET process during execution. Very useful for those times when for some reason you can't directly debug an ASP.NET application.


don't these result in some pretty unclear message boxes being display to a user if one of these happens in production? - Maslow
Well, yes, that's why you should #ifdef them out and/or remove them from production builds. - axel_c
(4) @Maslow, no - the Debug.Assert method is flagged with [Conditional("DEBUG")], which means calls to it get removed in non-DEBUG builds. Unless you build your production code with the DEBUG flag, in which case... - Danut Enachioiu
(2) use System.Diagnostics.Debugger.Launch() - Nissim
148
[+9] [2008-10-01 11:51:29] dariom

String interning. This is one that I haven't seen come up in this discussion yet. It's a little obscure, but in certain conditions it can be useful.

The CLR keeps a table of references to literal strings (and programmatically interned strings). If you use the same string in several places in your code it will be stored once in the table. This can ease the amount of memory required for allocating strings.

You can test if a string is interned by using String.IsInterned(string) [1] and you can intern a string using String.Intern(string) [2].

Note: The CLR can hold a reference to an interned string after application or even AppDomain end. See the MSDN documentation for details.

[1] http://msdn.microsoft.com/en-us/library/system.string.isinterned.aspx
[2] http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

Interned strings are held in small pages on the Large Object Heap. If your set of strings is unbounded, you will fragment the LOH with small, long-lived string intern pages. - Paul Ruane
149
[+9] [2008-11-24 12:51:58] Richard Ev

IEnumerable's SelectMany, which flattens a list of lists into a single list. Let's say I have a list of Orders, and each Order has a list of LineItems on that order.

I want to know the total number of LineItems sold...

int totalItems = Orders.Select(o => o.LineItems).SelectMany(i => i).Sum();

(11) int totalItems = Orders.SelectMany(o => o.LineItems).Sum(); - Pop Catalin
150
[+9] [2009-04-02 10:35:23] Waleed Eissa

Working with enums.

Convert a string to an Enum:

enum MyEnum
{
    FirstValue,
    SecondValue,
    ThirdValue
}

string enumValueString = "FirstValue";
MyEnum val = (MyEnum)Enum.Parse(typeof(MyEnum), enumValueString, true)
  • I use this to load the value of CacheItemPriority in my ASP.NET applications from a settings table in a database so that I can control caching (along with other settings) dynamically without taking the application down.

When comparing variables of type enum, you don't have to cast to int:

MyEnum val = MyEnum.SecondValue;
if (val < MyEnum.ThirdValue)
{
    // Do something
}

151
[+9] [2009-04-02 16:30:33] Gorkem Pacaci

I quite enjoy implicit generic parameters on functions. For example, if you have:

public void DoStuff<T>(T value);

Instead of calling it like this:

DoStuff<int>(5);

You can:

DoStuff(5);

And it'll work out the generic type from the parameter's type.

  • This doesn't work if you're calling the method through reflection.
  • I remember having some weird problems on Mono.

But it works only with one type parameter. As soon as you add two, it will force you to explicitely specify the Types. - user65199
152
[+9] [2010-03-01 22:37:19] Grokys

To test if an IEnumerable<T> is empty with LINQ, use:

IEnumerable<T>.Any();

  • At first, I was using (IEnumerable<T>.Count() != 0)...
    • Which unnecessarily causes all items in the IEnumerable<T> to be enumerated.
  • As an improvement to this, I went on to use (IEnumerable<T>.FirstOrDefault() == null)...
    • Which is better...
  • But IEnumerable<T>.Any() is the most succinct and performs the best.

Why is enumerable.FirstOrDefault() == null an improvement? - Jim G.
(1) Because it doesn't potentially cause the entire collection to be enumerated. - Grokys
(1) But doesn't Any() quit on the first find too? - Jim G.
Yes, it does. That's why it's the best solution. - Grokys
Enumerable.Count() == 0 is faster than Enumerable.Any() in cases where the collection has been enumerated and is an IList or array. - MattDavey
153
[+8] [2008-08-24 07:52:19] SemiColon

I'm pretty sure everyone is familiar with operator overloading, but maybe some aren't.

class myClass
{
    private string myClassValue = "";

    public myClass(string myString)
    {
        myClassValue = myString;
    }

    public override string ToString()
    {
        return myClassValue;
    }

    public static myClass operator <<(myClass mc, int shiftLen)
    {
        string newString = "";
        for (int i = shiftLen; i < mc.myClassValue.Length; i++)
            newString += mc.myClassValue[i].ToString();
        mc.myClassValue = newString.ToString();
        return mc;
    }

    public static myClass operator >>(myClass mc, int shiftLen)
    {
        char[] newString = new char[shiftLen + mc.myClassValue.Length];

        for (int i = shiftLen; i < mc.myClassValue.Length; i++)
            newString[i] += mc.myClassValue[i - shiftLen];

        mc.myClassValue = new string(newString);
        return mc;
    }

    public static myClass operator +(myClass mc, string args)
    {
        if (args.Trim().Length > 1)
            mc.myClassValue += args;
        return mc;
    }

    public static myClass operator -(myClass mc, string args)
    {
        if (args.Trim().Length > 1)
        {
            Regex rgx = new Regex(args);
            mc.myClassValue = rgx.Replace(mc.myClassValue, "");
        }
        return mc;
    }
}

I think it's pretty cool to be able to shift a string left and right using << and >> or to remove a set of strings that follow a regular expression pattern using -=

myClass tmpClass = new myClass("  HelloWorld123");
tmpClass -= @"World";
tmpClass <<= 2;
Console.WriteLine(tmpClass);

(4) As anyone who's worked with a C++ library that has lots of overloaded operators will tell you, overloaded operators are evil, evil, evil. Just write a method to do it. - endian
(3) Great for math classes. Makes, for example, multiplying vector and matrices very to read, just aVector = anotherVector* aMatrix; instead of aVector=anotherVector.Multiply(aMatrix); - Sorskoot
(2) Great for math classes, as @Sorskoot said, but that's about it. For pretty much any other class they're just really bad method names. - Danut Enachioiu
(1) There are certain limited cases, in addition to mathematical classes, where certain operators make sense. I see nothing wrong with, say, myCollection += anItem; or if(someObject == anotherObject) {}. - snarf
I think if you're going to overload operators like this you should a) make the class immutable and b) definitely NOT return a reference to one of the operands. - MattDavey
154
[+8] [2008-09-08 22:49:47] johnc

Not a C# specific thing, but I am a ternary operations junkie.

Instead of

if (boolean Condition)
{
    //Do Function
}
else
{
    //Do something else
}

you can use a succinct

booleanCondtion ? true operation : false operation;

e.g.

Instead of

int value = param;
if (doubleValue)
{
    value *= 2;
}
else
{
    value *= 3;
}

you can type

int value = param * (tripleValue ? 3 : 2);

It does help write succinct code, but nesting the damn things can be nasty, and they can be used for evil, but I love the little suckers nonetheless


For the sake of correctness, this pattern can only be used in situations like: if(condition) a = //some value else a = // other value - Olmo
It's great for conditional flags too -- flags = (shouldRun ? RUN : 0) | (shouldHide ? HIDE : 0); - lc.
I think making easy to maintain code is more important than making code that fits nicely on a line. Also, if someone wants to do this: else { // Do something else // and this other thing } Suddenly your single line ternary has to be converted to curly braces. - jcollum
155
[+8] [2008-10-13 22:32:10] Jan Bannister

You can switch on string!

switch(name)
{
  case "Dave":
    return true;
  case "Bob":
    return false;
  default:
    throw new ApplicationException();
}

Very handy! and a lot cleaner than a bunch of if-else statements


Wow! That really is surprising -- I always used a hashtable in such a case... Note that underlying CLR code here must be completely different than in a usual switch. - dbkk
Yes, it turns it into a bunch of gotos in CLR. - Arda Xi
156
[+8] [2009-05-04 19:57:08] rein

Instead of doing something cheesy like this:

Console.WriteLine("{0} item(s) found.", count);

I use the following inline trick:

Console.WriteLine("{0} item{1} found.", count, count==1 ? "" : "s");

This will display "item" when there's one item or "items" when there are more (or less) than 1. Not much effort for a little bit of professionalism.


(1) THis is fine for debugging but you'll hit a complete nightmare when you want to get into I18N and L10N - Jeff Yates
sweet solution to this often encountered issue - Peter Gfader
(3) yeah! internationalization will be a horror, but you could do the following: Console.WriteLine("{0} {1} found.", count, count==1 ? "item" : "items"); - Peter Gfader
@Peter I'm assuming you meant: Console.WriteLine("{0} {1}", count, count==1 ? "item found." : "items found."); - rein
(6) I use a Pluralise(value, singularname, pluralname) method that spits out the entire "5 items" string. This is much more readable, supports "goose/geese" pluralisation and is much easier to find and deal with when it comes to localisation. - Jason Williams
157
[+8] [2009-08-07 00:13:41] JoshL

Expression to initialize a Dictionary in C# 3.5:

new Dictionary<string, Int64>() {{"Testing", 123}, {"Test", 125}};


158
[+8] [2009-11-05 00:10:43] plaureano

C# allows you to add property setter methods to concrete types that implement readonly interface properties even though the interface declaration itself has no property setter. For example:

public interface IReadOnlyFoo
{
   object SomeReadOnlyProperty { get; }
}

The concrete class looks like this:

internal class Foo : IReadOnlyFoo
{
   public object SomeReadOnlyProperty { get; internal set; }
}

What's interesting about this is that the Foo class is immutable if you cast it to the IReadOnlyFoo interface:

// Create a Foo instance
Foo foo = new Foo();

// This statement is legal
foo.SomeReadOnlyProperty = 12345;

// Make Foo read only
IReadOnlyFoo readOnlyFoo = foo;

// This statement won't compile
readOnlyFoo.SomeReadOnlyProperty = 54321;

What if they cast it back to Foo? - ChaosPandion
Good point. I find it useful for most interfaces to have read-only properties. After all, interfaces describe behaviour and you normally (or perhaps 'should only') invoke behaviour through methods and not setting properties. - Steve Dunn
I usually use a protected setter for this purpose. My class has a copy constructor which allows all the values to be set from the object being passed in. I then have a derived class that overrides the "readonly" properties return new ReadOnlyObject(new WriteableVersion() { Property1 = value, //Set all writeable fields... }); - BenAlabaster
+100 if I could for having a mutable object with an immutable interface. - MattDavey
159
[+8] [2009-12-07 08:26:16] Matt Dotson

Dictionary initializers are always useful for quick hacks and unit tests where you need to hardcode some data.

var dict = new Dictionary<int, string> { { 10, "Hello" }, { 20, "World" } };

160
[+8] [2010-03-20 18:00:45] user287107

With LINQ it's possible to create new functions based on parameters. That's very nice if you have a tiny function which is exectued very often, but the parameters need some time to calculate.

    public Func<int> RandomGenerator
    {
        get
        {
            var r = new Random();
            return () => { return r.Next(); };
        }
    }

    void SomeFunction()
    {
        var result1 = RandomGenerator();

        var x = RandomGenerator;
        var result2 = x();
    }

Actually, that's not LINQ, but lambda expressions. - gimpf
And if you keep creating Random objects over and over, the quality of seeds will suffer. Much better (also space and time wise) to just allocate a static one to use and define it once. - Rubys
(2) no, thats the interesting point, a random object is just created the first time - user287107
(1) +1 Not a feature on itself, but an interesting and ridiculously easy pattern for lazy initialization! - Abel
@user287107 No, that's not true, a new random will be created every time the property is accessed. Two times in your example. However if you held on to the delegate returned from the property only a single random is created even though you can call the delegate multiple times. - Patrik Hägne
And no reason to have that property. Any block scope can effectively be a closure - sehe
161
[+7] [2008-08-14 11:07:01] Serhat Ozgel

In addition to duncansmart's reply, also extension methods can be used on Framework 2.0. Just add an ExtensionAttribute class under System.Runtime.CompilerServices namespace and you can use extension methods (only with C# 3.0 of course).

namespace System.Runtime.CompilerServices
{
    public class ExtensionAttribute : Attribute
    { 
    }
}

162
[+7] [2008-08-20 19:17:16] Nelson Miranda

You type "prop" and then press [TAB] twice, it generates useful code for your properties and can speed your typing.

I know this works in VS 2005 (I use it) but I don´t know in previous versions.


I think it's VS 2005 and up. I use it a lot :-) - Rob
Coderush shortens it to 'p' ;) - George Mauer
This is not a feature per se. It's a Visual Studio code snippet. You can create your own snippets, or even find some on internet. Check Dr WPF's code snippets, for example. - LBugnion
(3) ctor can be used to create a constructor - Bhaskar
Ctrl K, Ctrl X shows all the snippets available in Visual Studio. - Patrick
163
[+7] [2008-10-25 09:53:31] splattne

Object.ReferenceEquals Method

Determines whether the specified Object instances are the same instance.

Parameters:

  • objA: System.Object - The first Object to compare.
  • objB: System.Object - The second Object to compare.

Example:

 object o = null;
 object p = null;
 object q = new Object();

 Console.WriteLine(Object.ReferenceEquals(o, p));
 p = q;
 Console.WriteLine(Object.ReferenceEquals(p, q));
 Console.WriteLine(Object.ReferenceEquals(o, p));

Difference to "==" and ".Equals":

Basically, Equals() tests of object A has the same content as object B.

The method System.Object.ReferenceEquals() always compares references. Although a class can provide its own behavior for the equality operator (below), that re-defined operator isn't invoked if the operator is called via a reference to System.Object.

For strings there isn't really a difference, because both == and Equals have been overriden to compare the content of the string.

See also this answer [1] to another question ("How do I check for nulls in an ‘==’ operator overload without infinite recursion?").

[1] https://stackoverflow.com/questions/73713/how-do-i-check-for-nulls-in-an-operator-overload-without-infinite-recursion#73732

164
[+7] [2008-11-18 15:56:03] Rytmis

Explicit interface member implementation [1], wherein an interface member is implemented, but hidden unless the instance is cast to the interface type.

[1] http://msdn.microsoft.com/en-us/library/aa664591(VS.71).aspx

165
[+7] [2008-11-25 22:53:40] Rob

This isn't a C# specific type, but I just found the ISurrogateSelector and ISerializationSurrogate interfaces --

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.isurrogateselector.aspx

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.isurrogateselector.aspx

Using these in conjunction with the BinaryFormatter allows for non-serializable objects to be serialized via the implementation of a surrogate class. The surrogate pattern is well-understood in computer science, particularly when dealing with the problem of serialization. I think that this implementation is just tucked away as a parameter of the constructor to BinaryFormatter, and that's too bad.

Still - VERY hidden. :)


(1) some example on how to use it? - chakrit
166
[+7] [2008-12-15 15:03:09] amazedsaint

dynamic keyword in C# 4.0

You can use dynamic keyword, if you want your method calls to be resolved only at the runtime.

dynamic invoker=new DynamicInvoker();
dynamic result1=invoker.MyMethod1();
dynamic result2=invoker.MyMethod2();

Here I'm implementing a dynamic invoker.

public class DynamicInvoker : IDynamicObject
    {
        public MetaObject GetMetaObject
              (System.Linq.Expressions.Expression parameter)
        {
            return new DynamicReaderDispatch (parameter);
        }
    }

    public class DynamicDispatcher : MetaObject
    {
        public DynamicDispatcher (Expression parameter) 
                   : base(parameter, Restrictions.Empty){ }

        public override MetaObject Call(CallAction action, MetaObject[] args)
        {
            //You'll get MyMethod1 and MyMethod2 here (and what ever you call)
            Console.WriteLine("Logic to invoke Method '{0}'", action.Name);
            return this; //Return a meta object
        }
    }

167
[+7] [2009-01-24 05:22:17] JohnOpincar

You can have generic methods in a non-generic class.


168
[+7] [2009-01-31 04:50:20] Andrew Peters

Cool trick to emulate functional "wildcard" arguments (like '_' in Haskell) when using lambdas:

(_, b, __) => b.DoStuff();  // only interested in b here

(9) Not really a trick, just a naming choice. I think it looks daft since you're forced to use increasing numbers of underscores. - xyz
169
[+7] [2009-04-01 21:50:41] dso

Here's one I discovered recently which has been useful:

Microsoft.VisualBasic.Logging.FileLogTraceListener

MSDN Link [1]

This is a TraceListener implementation which has a lot of features, such as automatic log file roll over, which I previously would use a custom logging framework for. The nice thing is that it is a core part of .NET and is integrated with the Trace framework, so its easy to pick up and use immediately.

This is "hidden" because its in the Microsoft.VisualBasic assembly... but you can use it from C# as well.

[1] http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.logging.filelogtracelistener.aspx

A lot of people use log4net or the enterprises library's log features. Do you think that Microsoft.VisualBasic.Logging.FileLogTraceListener is a better choice? - tuinstoel
Probably not as full featured as those other ones. But to repeat myself: "The nice thing is that it is a core part of .NET and is integrated with the Trace framework, so its easy to pick up and use immediately." - dso
170
[+7] [2009-04-26 16:11:10] Elroy

The usage of the default keyword in generic code to return the default value for a type.

public class GenericList<T>
{
    private class Node
    {
        //...

        public Node Next;
        public T Data;
    }

    private Node head;

    //...

    public T GetNext()
    {
        T temp = default(T);

        Node current = head;
        if (current != null)
        {
            temp = current.Data;
            current = current.Next;
        }
        return temp;
    }
}

Another example here [1]

[1] https://stackoverflow.com/questions/367378/returning-a-default-value-c

171
[+7] [2009-05-14 09:05:37] Ash

The built-in (2.0) MethodInvoker delegate is useful when you want to Invoke/BeginInvoke inline code. This avoids needing to create an actual delegate and separate method.

    void FileMessageEvent(object sender, MessageEventArgs e)
    {

        if (this.InvokeRequired == true)
        {
            this.BeginInvoke((MethodInvoker)delegate { 
                     lblMessage.Text=e.Message; 
                     Application.DoEvents(); 
                 }
            ); 

        }
    }

Resolves the error: "Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type".


172
[+7] [2009-05-19 15:52:52] JoshL

Array initialization without specifying the array element type:

var pets = new[] { "Cat", "Dog", "Bird" };

(6) also: string[] pets = {"Cat", "Dog", "Bird"}; - P Daddy
@P Daddy thanks for reminding me I can do this even shorter and more legible - sehe
173
[+7] [2009-06-03 15:03:23] Lloyd Powell

Properties to display when viewing components Properties in design view:

private double _Zoom = 1;

[Category("View")]
[Description("The Current Zoom Level")]
public double Zoom
{
get { return _Zoom;}
set { _Zoom = value;}
}

Makes things a lot easier for other users of your component libraries.


I haven't made any components so far, so this is a place I wish I could bookmark responses instead of just the question - Maslow
174
[+7] [2009-06-14 17:31:46] ShuggyCoUk

Advanced Debugging

Display

The already mentioned attributes DebuggerDisplay and DebuggerBrowsable control the visibility of elements and the textual value displayed. Simply overriding ToString() will cause the debugger to use the output of that method.

If you want more complex output you can use/create a Debugger Visualizer [1], several examples are available here [2].

Son Of Strike

Microsoft provide a debugger extension known as SOS [3]. This is an extremely powerful (though often confusing) extension which is an excellent way to diagnose 'leaks', more accurately unwanted references to objects no longer required.

Symbol Server for framework source

Following these instructions [4] will allow you to step through the source of some parts of the framework.

Changes in 2010

Several enhancements and new features exist in Visual Studio 2010:

[1] http://msdn.microsoft.com/en-us/library/zayyhzts.aspx
[2] http://www.dotnetpowered.com/DebuggerVisualizers.aspx
[3] http://msdn.microsoft.com/en-us/library/bb190764(vs.80).aspx
[4] http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx
[5] http://www.danielmoth.com/Blog/2009/05/parallel-tasks-new-visual-studio-2010.html
[6] http://www.danielmoth.com/Blog/2009/05/parallel-stacks-another-new-vs2010.html
[7] http://channel9.msdn.com/posts/VisualStudio/Historical-Debugger-and-Test-Impact-Analysis-in-Visual-Studio-Team-System-2010/

175
[+7] [2009-06-19 01:59:31] SLaks

You can create delegates from extension methods as if they were regular methods, currying the this parameter. For example,

static class FunnyExtension {
    public static string Double(this string str) { return str + str; }
    public static int Double(this int num) { return num + num; }
}


Func<string> aaMaker = "a".Double;
Func<string, string> doubler = FunnyExtension.Double;

Console.WriteLine(aaMaker());       //Prints "aa"
Console.WriteLine(doubler("b"));    //Prints "bb"

Note that this won't work on extension methods that extend a value type; see this question [1].

[1] https://stackoverflow.com/questions/1016033/extension-methods-defined-on-value-types-cannot-be-used-to-create-delegates-why

(1) @MattDavey: One use for this (which is actually how I discovered it) is SomeEvent += OtherEvent.Raise, where Raise is a custom extension method. The difference between that and SomeEvent += OtherEvent is left as an exercise to the reader (it's substantial). I may write a blog post about this at some point. - SLaks
176
[+7] [2009-06-22 05:42:31] John
HttpContext.Current.Server.Execute 

is great for rendering HTML to strings for AJAX callbacks. You can use this with a component instead of piecing together HTML string snippets. I was able to cut page bloat down a couple of hundred KB with virtually no mess. I used it like this:

Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl(@"MyComponent.ascx");
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();

+1. Good tool for unit / integration testing. - RickNZ
177
[+7] [2009-07-22 01:42:45] Martin Konicek
[field: NonSerialized]
public event EventHandler Event;

This way, the event listener is not serialized.

Just [NonSerialized] does not work, because NonSerializedAttribute can only be applied to fields.


178
[+7] [2009-08-07 06:37:19] ata

I don't think someone has mentioned that appending ? after a value type name will make it nullable.

You can do:

DateTime? date = null;

DateTime is a structure.


Nullable<T> is not a hidden feature... - Thomas Levesque
(1) Neither is most of these... The point of this question is to show things that most c# devs may not know. I would definitely upvote this since it's not something i think most people know about. (the adding ? to get a nullable, not the nullable itself) - RCIX
179
[+7] [2009-08-14 12:13:18] Ali Ersöz

Four switch oddities [1] by Eric Lippert

[1] http://blogs.msdn.com/ericlippert/archive/2009/08/13/four-switch-oddities.aspx

180
[+7] [2009-08-21 11:30:38] Minta szerződés

The ability to use LINQ to do inline work on collections that used to take iteration and conditionals can be incredibly valuable. It's worth learning how all the LINQ extension methods can help make your code much more compact and maintainable.


181
[+7] [2010-04-05 12:25:40] Nakul Chaudhary

I like

#if DEBUG
           //Code run in debugging mode

#else
           //Code run in release mode

#endif

I wouldn't say it's exactly a hidden feature, but in all the C# books that I've read, it isn't something that's talked about a lot. A nice reminder at the very least. - Pretzel
(4) Although this can be handy it should be used with care. I have seen a couple of cases where deployed code behaved differently from local code. - basvo
(2) Using the Conditional attribute is often a better solution than using #if. msdn.microsoft.com/en-us/library/aa664622%28VS.71%29.aspx - Ergwun
182
[+7] [2010-05-14 18:46:21] Pretzel

I was reading thru the book "Pro ASP.NET MVC Framework" (APress) and observed something the author was doing with a Dictionary object that was foreign to me.

He added a new Key/Value Pair without using the Add() method. He then overwrote that same Key/Value pair without having to check if that key already existed. For example:

Dictionary<string, int> nameAgeDict = new Dictionary<string, int>();
nameAgeDict["Joe"] = 34;      // no error. will just auto-add key/value
nameAgeDict["Joe"] = 41;      // no error. key/value just get overwritten
nameAgeDict.Add("Joe", 30);   // ERROR! key already exists

There are many cases where I don't need to check if my Dictionary already has a key or not and I just want to add the respective key/value pair (overwriting the existing key/value pair, if necessary.) Prior to this discovery, I would always have to check to see if the key already existed before adding it.


183
[+7] [2010-07-06 19:46:43] WedTM

Not sure if this one has been mentioned or not (11 pages!!)

But the OptionalField attribute for classes is amazing when you are versioning classes/objects that are going to be serialized.

http://msdn.microsoft.com/en-us/library/ms229752(VS.80).aspx


184
[+6] [2008-08-12 18:40:45] Iain Holder

@Brad Barker

I think if you have to use nullable types, it's better to use Nullable<.T> rather than the question mark notation. It makes it eye-achingly obvious that magic is occurring. Not sure why anyone would ever want to use Nullable<.bool> though. :-)

Krzysztof Cwalina (one of the authors of Framwork Design Guidlines) has a good post here: http://blogs.msdn.com/kcwalina/archive/2008/07/16/Nullable.aspx

And Mike Hadlow has a nice post on Nullability Voodoo [1]

[1] http://mikehadlow.blogspot.com/2006/10/nullability-voodoo.html

Not sure I agree with Mike Hadlow. Sounds like someone who has spent a long time using languages and dbs without good null support and is a little 'afraid' of changing. Use of null in business terms is usually obvious. It means "don't know", or "doesn't have one" (i.e. "doesn't have an end date"). - cbp
"Not sure why anyone would ever want to use Nullable<.bool> though" How about when you are interacting with BIT columns from an SQL Server database? A BIT datatype in T-SQL can return 1, 0 or NULL and can be directyly converted to a Nullable<Bool> by .NET Nullables are extremely useful when dealing with data in databases, as "value types" can actually be NULL. - Dan Diplo
@cbp and @Dan Dilpo - You could argue that if you're allowing nulls in a value type like a bool you should be using something else. - Iain Holder
Easy, a null bool is FileNotFound!! thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx - Axeman
185
[+6] [2008-08-12 19:40:28] BinaryMisfit

In no particular order:

Lists<>
Mutex

The new property definitions shortcut in Framework 3.5.


186
[+6] [2008-08-25 15:09:18] David Basarab

In reading the book on development of the .NET framework. A good piece of advice is not to use bool to turn stuff on or off, but rather use ENums.

With ENums you give yourself some expandability without having to rewrite any code to add a new feature to a function.


and besides they are more descriptive - Beatles1692
And they allow you to make your API harder to use incorrectly. Picture a method with a bunch of boolean parameters. - Dave Van den Eynde
187
[+6] [2008-08-28 20:07:41] chakrit

Thought about @dp AnonCast and decided to try it out a bit. Here's what I come up with that might be useful to some:

// using the concepts of dp's AnonCast
static Func<T> TypeCurry<T>(Func<object> f, T type)
{
    return () => (T)f();
}

And here's how it might be used:

static void Main(string[] args)
{

    var getRandomObjectX = TypeCurry(GetRandomObject,
        new { Name = default(string), Badges = default(int) });

    do {

        var obj = getRandomObjectX();

        Console.WriteLine("Name : {0} Badges : {1}",
            obj.Name,
            obj.Badges);

    } while (Console.ReadKey().Key != ConsoleKey.Escape);

}

static Random r = new Random();
static object GetRandomObject()
{
    return new {
        Name = Guid.NewGuid().ToString().Substring(0, 4),
        Badges = r.Next(0, 100)
    };
}

Doesn't matter what it actually does, I would FIND a use for a method called TypeCurry! ;D - user246091
188
[+6] [2008-09-17 20:28:37] Sixto Saez

new modifier

Usage of the "new" modifier in C# is not exactly hidden but it's not often seen. The new modifier comes in handy when you need to "hide" base class members and not always override them. This means when you cast the derived class as the base class then the "hidden" method becomes visible and is called instead of the same method in the derived class.

It is easier to see in code:

public class BaseFoo
{
    virtual public void DoSomething()
    {
        Console.WriteLine("Foo");
    }
}

public class DerivedFoo : BaseFoo
{
    public new void DoSomething()
    {
        Console.WriteLine("Bar");
    }
}

public class DerivedBar : BaseFoo
{
    public override void DoSomething()
    {
        Console.WriteLine("FooBar");
    }
}

class Program
{
    static void Main(string[] args)
    {
        BaseFoo derivedBarAsBaseFoo = new DerivedBar();
        BaseFoo derivedFooAsBaseFoo = new DerivedFoo();

        DerivedFoo derivedFoo = new DerivedFoo();

        derivedFooAsBaseFoo.DoSomething(); //Prints "Foo" when you might expect "Bar"
        derivedBarAsBaseFoo.DoSomething(); //Prints "FooBar"

        derivedFoo.DoSomething(); //Prints "Bar"
    }
}

[Ed: Do I get extra points for puns? Sorry, couldn't be helped.]


//Prints "Foo" when you might expect "Bar" I think that comment says it all. The program no longer operates as expected. Member hiding in this way is unwise. It does not have the semantics of overriding. See: blog.colinmackay.net/archive/2008/10/10/4264.aspx - Colin Mackay
189
[+6] [2008-09-19 15:59:09] ilitirit

Literals can be used as variables of that type. eg.

Console.WriteLine(5.ToString());
Console.WriteLine(5M.GetType());   // Returns "System.Decimal"
Console.WriteLine("This is a string!!!".Replace("!!", "!"));

Just a bit of trivia...

There's quite a few things people haven't mentioned, but they have mostly to do with unsafe constructs. Here's one that can be used by "regular" code though:

The checked/unchecked keywords:

public static int UncheckedAddition(int a, int b)
{
    unchecked { return a + b; }
}

public static int CheckedAddition(int a, int b)
{
    checked { return a + b; } // or "return checked(a + b)";
}

public static void Main() 
{
    Console.WriteLine("Unchecked: " + UncheckedAddition(Int32.MaxValue, + 1));  // "Wraps around"
    Console.WriteLine("Checked: " + CheckedAddition(Int32.MaxValue, + 1));  // Throws an Overflow exception
    Console.ReadLine();
}

190
[+6] [2008-10-06 21:16:08] Patrick Szalapski

Instead of using int.TryParse() or Convert.ToInt32(), I like having a static integer parsing function that returns null when it can't parse. Then I can use ?? and the ternary operator together to more clearly ensure my declaration and initialization are all done on one line in a easy-to-understand way.

public static class Parser {
    public static int? ParseInt(string s) {
        int result;
        bool parsed = int.TryParse(s, out result);
        if (parsed) return result;
        else return null;
    }
    // ...
}

This is also good to avoid duplicating the left side of an assignment, but even better to avoid duplicating long calls on the right side of an assignment, such as a database calls in the following example. Instead of ugly if-then trees (which I run into often):

int x = 0;
YourDatabaseResultSet data = new YourDatabaseResultSet();
if (cond1)
    if (int.TryParse(x_input, x)){
        data = YourDatabaseAccessMethod("my_proc_name", 2, x);
    }
    else{
        x = -1;
        // do something to report "Can't Parse"    
    }
}
else {
    x = y;
    data = YourDatabaseAccessMethod("my_proc_name", 
       new SqlParameter("@param1", 2),
       new SqlParameter("@param2", x));
}

You can do:

int x = cond1 ? (Parser.ParseInt(x_input) ?? -1) : y;
if (x >= 0)  data = YourDatabaseAccessMethod("my_proc_name", 
    new SqlParameter("@param1", 2),
    new SqlParameter("@param2", x));

Much cleaner and easier to understand


+1. And you could make it an extension method if you don't mind to have one more method to appear in IntelliSense for strings - Roman Boiko
Couldn't you just make the method ParseIntOrDefault(string input, int default)? - MattDavey
You could, but it is less readable, in my opinion. - Patrick Szalapski
191
[+6] [2008-11-04 23:24:03] Cohen

Math.Max and Min to check boundaries: I 've seen this in a lot of code:

if (x < lowerBoundary) 
{
   x = lowerBoundary;
}

I find this smaller, cleaner and more readable:

x = Math.Max(x, lowerBoundary);

Or you can also use a ternary operator:

x = ( x < lowerBoundary) ? lowerBoundary : x;

(1) I think Math.min is much more readable than the ternary operator. - tuinstoel
I personally agree, but apparently not everyone agrees: refactormycode.com/codes/692-which-is-more-readable-math-or-‌​if - Cohen
Should be 'x = Math.Max(x, lowerBoundary);' - codybartfast
@it depends: so true, how could I have missed it.. doh! corrected! - Cohen
@Cohen & others: I find myself eternally getting Min and Max backwards (it is a semantic issue: does then name Min()/Max() signify the goal or the relative operation?). So I stick with a custom helper: i = MinMax(i,a,b); - sehe
@sehe: you lost me what does the MinMax exactly do? I see Min as from the paramters supplied return the lowest number. You have multiple inputs and one return value. I wonder how you interprete it differently? - Cohen
@Cohen: clarifying: i = MinMax(i,minval,maxval). I try not to interpret Min or Max differently, but I guess what sometimes happens is that I misread Min(a,100) to mean something like 'a, but at a minimum of 100'. The catch is in that when you want to impose a maximum you need to use the Min() function, and viceversa. It catches me out all the time. Even when I'm on my guard :) - sehe
Also note that my MinMax() helpers could be named 'LimitRange' or something. Equivalences MinMax(i,i,maxval) === Min(i, maxval) and MinMax(i,minval,i) === Max(i, minval). I find that this confuses the heck out me when seeing them next to eachother, but never confuses me when using MinMax in isolation. Min and Max in isolation do confuse me regularly. - sehe
192
[+6] [2008-11-06 21:47:46] Dmitri Nesteruk

Mixins are a nice feature. Basically, mixins let you have concrete code for an interface instead of a class. Then, just implement the interface in a bunch of classes, and you automatically get mixin functionality. For example, to mix in deep copying into several classes, define an interface

internal interface IPrototype<T> { }

Add functionality for this interface

internal static class Prototype
{
  public static T DeepCopy<T>(this IPrototype<T> target)
  {
    T copy;
    using (var stream = new MemoryStream())
    {
      var formatter = new BinaryFormatter();
      formatter.Serialize(stream, (T)target);
      stream.Seek(0, SeekOrigin.Begin);
      copy = (T) formatter.Deserialize(stream);
      stream.Close();
    }
    return copy;
  }
}

Then implement interface in any type to get a mixin.


I get the concept...but..."mixins" makes me think of the ice cream shop. Isn't there some other term for these? - Ryan Lundy
Is this similiar to what castle dynamic proxy does? - Bless Yahu
They really are called mixins. It's a term that comes from C++ where mixing were abstract superclasses or some such. In C#, they are just done using extension methods over interfaces. - Dmitri Nesteruk
Another name for mix-ins is often "trait". - user52898
In C++ mixins are most often defined as template base classes parameterized by the descendant type (sic). In C++ this is a viable pattern because you can (a) avoid polymorphism explicitely (b) have multiple base classes. In CLR and competing VMs this is not so convenient, hence the 'pattern' (or paradigm) maps (somewhat) nicely on the pattern outlined in this answer. - sehe
193
[+6] [2008-11-17 09:28:42] Eyvind

Regarding foreach: It does not use 'duck typing', as duck typing IMO refers to a runtime check. It uses structural type checking (as opposed to nominal) at compile time to check for the required method in the type.


(1) yeah duck typing should be reserved for full dynamics IMHO too; however: foreach does use duck typing in that it will coerce .NET 1.1 (non-generic) GetEnumerator() iterators for you at runtime (this happens to be both a pitfall and the reason for Cast<> to be so convenient). - sehe
194
[+6] [2008-11-18 15:52:15] Bryan Watts

(I just used this one) Set a field null and return it without an intermediate variable:

try
{
    return _field;
}
finally
{
    _field = null;
}

Nice hack :), it's clearly not "clear intent" in this code. - Pop Catalin
(1) It's an idiom, like the ternary operator. Try/finally have a temporal relationship, so I think that reads quite nice, once you've seen it before :-) - Bryan Watts
(3) Clever, but a difficult read. Most developer's minds go right to try/catch when they see a "try" in the code. Also, I can't think of a lot of situations where this would be useful. There's probably a property to wrap that member, and when in the world would you have a method that was like DoSomestuffToAMemberReturnItToMeThenNullIt()? hehe. Just seems counterintuitive. I'm with Guillaume on this one. - Ben Lesh
(1) The usage I mentioned originally was for a builder pattern. At the end of .Build(), I return the member variable holding the instance and null it out to indicate the build is complete. Perfect application of this technique, and no property involved. Also, "try/finally" blocks are pervasive; I don't agree with your assertion that most developers immediately think of "try/catch" when they see "try". - Bryan Watts
195
[+6] [2008-12-16 22:16:59] Steven Behnke

This isn't a C# specific feature but it is an addon that I find very useful. It is called the Resource Refactoring Tool. It allows you to right click on a literal string and extract it into a resource file. It will search the code and find any other literal strings that match and replace it with the same resource from the Resx file.

http://www.codeplex.com/ResourceRefactoring


196
[+6] [2008-12-30 01:40:37] TheUberOverLord

I call this AutoDebug because you can drop right into debug where and when you need based on a bool value which could also be stored as a project user setting as well.

Example:

//Place at top of your code
public UseAutoDebug = true;


//Place anywhere in your code including catch areas in try/catch blocks
Debug.Assert(!this.UseAutoDebug);

Simply place the above in try/catch blocks or other areas of your code and set UseAutoDebug to true or false and drop into debug anytime you wish for testing.

You can leave this code in place and toggle this feature on and off when testing, You can also save it as a Project Setting, and manually change it after deployment to get additional bug information from users when/if needed as well.

You can see a functional and working example of using this technique in this Visual Studio C# Project Template here, where it is used heavily:

http://code.msdn.microsoft.com/SEHE


197
[+6] [2009-02-27 00:45:20] Jonathan Parker

Method groups aren't well known.

Given:

Func<Func<int,int>,int,int> myFunc1 = (i, j) => i(j);
Func<int, int> myFunc2 = i => i + 2;

You can do this:

var x = myFunc1(myFunc2, 1);

instead of this:

var x = myFunc1(z => myFunc2(z), 1);

Which is the same as saying, given List<int> items = { 1, 3, 5, 7, 11} ;, that you can do var total = items.Sum(myFunc2); instead of var total = items.Sum(i => myFunc2(i));. - ANeves
No need for higher-order lambdas in a basic example of Method Groups - sehe
198
[+6] [2009-05-08 18:21:05] Jeff Yates

I am so so late to this question, but I wanted to add a few that I don't think have been covered. These aren't C#-specific, but I think they're worthy of mention for any C# developer.

AmbientValueAttribute

[1] This is similar to DefaultValueAttribute, but instead of providing the value that a property defaults to, it provides the value that a property uses to decide whether to request its value from somewhere else. For example, for many controls in WinForms, their ForeColor and BackColor properties have an AmbientValue of Color.Empty so that they know to get their colors from their parent control.

IsolatedStorageSettings

[2] This is a Silverlight one. The framework handily includes this sealed class for providing settings persistence at both the per-application and per-site level.

Flag interaction with extension methods

Using extension methods, flag enumeration use can be a lot more readable.

    public static bool Contains(
          this MyEnumType enumValue,
          MyEnumType flagValue)
    {
        return ((enumValue & flagValue) == flagValue);
    }

    public static bool ContainsAny(
          this MyEnumType enumValue,
          MyEnumType flagValue)
    {
        return ((enumValue & flagValue) > 0);
    }

This makes checks for flag values nice and easy to read and write. Of course, it would be nicer if we could use generics and enforce T to be an enum, but that isn't allowed. Perhaps dynamic will make this easier.

[1] http://msdn.microsoft.com/en-us/library/system.componentmodel.ambientvalueattribute.aspx
[2] http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragesettings(VS.95).aspx

199
[+6] [2009-05-17 08:41:55] Josef Pfleger

I find it incredible what type of trouble the compiler goes through to sugar code the use of Outer Variables:

string output = "helo world!";
Action action = () => Console.WriteLine(output);
output = "hello!";
action();

This actually prints hello!. Why? Because the compiler creates a nested class for the delegate, with public fields for all outer variables and inserts setting-code before every single call to the delegate :) Here is above code 'reflectored':

Action action;
<>c__DisplayClass1 CS$<>8__locals2;
CS$<>8__locals2 = new <>c__DisplayClass1();
CS$<>8__locals2.output = "helo world!";
action = new Action(CS$<>8__locals2.<Main>b__0);
CS$<>8__locals2.output = "hello!";
action();

Pretty cool I think.


May I also point out that Java for instance doesn't even allow the use of non-final outer variables in their anonymous methods... - Josef Pfleger
The technical term for this is 'closure'. You cannot believe that C# actually implements closures. Well, the Java folks dure can't believe it either, but numerous other languages have had this before - so it probably just reflects your background in languages - sehe
200
[+6] [2009-05-19 11:00:33] Shalom Craimer

I couldn't figure out what use some of the functions in the Convert class had (such as Convert.ToDouble(int), Convert.ToInt(double)) until I combined them with Array.ConvertAll:

int[] someArrayYouHaveAsInt;
double[] copyOfArrayAsDouble = Array.ConvertAll<int, double>(
                                someArrayYouHaveAsInt,
                                new Converter<int,double>(Convert.ToDouble));

Which avoids the resource allocation issues that arise from defining an inline delegate/closure (and slightly more readable):

int[] someArrayYouHaveAsInt;
double[] copyOfArrayAsDouble = Array.ConvertAll<int, double>(
                                someArrayYouHaveAsInt,
                                new Converter<int,double>(
                                  delegate(int i) { return (double)i; }
                                ));

I use Convert.ToDouble, ToInt, etc all the time, not especially for arrays... It's really handy because if an object can be converted one way or another, it will, which is not the case with a cast : for instance you can't cast a string to a Double, you have to use Double.Parse. Or a variable of type object, containing a Decimal, can't be cast to int directly. Convert.ToDouble or ToInt will use the most appropriate way to convert the value, whatever it is. - Thomas Levesque
201
[+6] [2009-05-26 21:23:24] sourcenouveau

Having just learned the meaning of invariance, covariance and contravariance, I discovered the in [1] and out [2] generic modifiers that will be included in .NET 4.0. They seem obscure enough that most programmers would not know about them.

There's an article [3] at Visual Studio Magazine which discusses these keywords and how they will be used.

[1] http://msdn.microsoft.com/en-us/library/dd469484(VS.100).aspx
[2] http://msdn.microsoft.com/en-us/library/dd469487(VS.100).aspx
[3] http://visualstudiomagazine.com/articles/2009/05/01/generic-covariance-and-contravariance-in-c-40.aspx

202
[+6] [2009-06-07 07:26:09] Tolgahan Albayrak

The data type can be defined for an enumeration:

enum EnumName : [byte, char, int16, int32, int64, uint16, uint32, uint64]
{
    A = 1,
    B = 2
}

once, i used this feature creating structure database and marshalling - Tolgahan Albayrak
it's not a "hidden feature", it's clearly documented... - Thomas Levesque
(5) most of the features above are documented too.. - Tolgahan Albayrak
Most of the hidden features series of S.O. questions are hidden, or rarely used. this is rarely used and easily missed. I would have imagined it was possible to do it, but not known the syntax nor expected it would support unsigned values. - Maslow
203
[+6] [2009-06-18 03:44:34] statenjason

The Yield keyword is often overlooked when it has a lot of power. I blogged about it awhile ago and discussed benefits (differed processing) and happens under the hood of yield to help give a stronger understanding.

Using Yield in C# [1]

[1] http://jxs.me/2010/05/14/using-yield-in-c/

+1 not hidden but vastly underrated. Vastly. Underrated. (people are taking it for granted thinking it is jut for enumerating) - sehe
+1 Using yield you prevent from creating temporary lists (from your blog) - riezebosch
204
[+6] [2009-07-13 11:05:00] softveda

Pointers in C#.

They can be used to do in-place string manipulation. This is an unsafe feature so the unsafe keyword is used to mark the region of unsafe code. Also note how the fixed keyword is used to indicate that the memory pointed to is pinned and cannot be moved by the GC. This is essential a pointers point to memory addresses and the GC can move the memory to different address otherwise resulting in an invalid pointer.

    string str = "some string";
    Console.WriteLine(str);
    unsafe
    {
        fixed(char *s = str)
        {
            char *c = s;
            while(*c != '\0')
            {
                *c = Char.ToUpper(*c++);                    
            }
        }
    }
    Console.WriteLine(str);

I wouldn't ever do it but just for the sake of this question to demonstrate this feature.


if you have to use the unsafe keyword you're doing it wrong! :P - Aaron Powell
(4) Not necessarily...using unsafe code may improve performance significantly see "stackoverflow.com/questions/541331/…" - Sandeep Datta
205
[+6] [2009-07-22 08:39:34] netzer

I especially like the nullable DateTime. So if you have some cases where a Date is given and other cases where no Date is given I think this is best to use and IMHO easier to understand as using DateTime.MinValue or anything else...

DateTime? myDate = null;

if (myDate.HasValue)
{
    //doSomething
}
else
{
    //soSomethingElse
}

You can replace .HasValue for == null. Comparing a nullable which is set to null with myVar == null will give you a true. - Gertjan
206
[+6] [2009-09-27 19:04:44] Mike Valenty

Open generics are another handy feature especially when using Inversion of Control [1]:

container.RegisterType(typeof(IRepository<>), typeof(NHibernateRepository<>));
[1] http://en.wikipedia.org/wiki/Inversion_of_control

(1) In this case using Unity IoC container, this will tell the container resolve the closed generic concrete class NHibernateRepository<T> for any requested IRepository<T>. For example, var repository = container.Resolve<IRepository<Customer>>(); would return NHibernateRepository<Customer>; - Mike Valenty
207
[+6] [2010-01-09 01:48:03] t0mm13b

Having read through all 9 pages of this I felt I had to point out a little unknown feature...

This was held true for .NET 1.1, using compression/decompression on gzipped files, one had to either:

  • Download ICSharpCode.ZipLib [1]
  • Or, reference the Java library into your project and use the Java's in-built library to take advantage of the GZip's compression/decompression methods.

It is underused, that I did not know about, (still use ICSharpCode.ZipLib still, even with .NET 2/3.5) was that it was incorporated into the standard BCL version 2 upwards, in the System.IO.Compression namespace... see the MSDN page " GZipStream Class [2]".

[1] http://www.icsharpcode.net/OpenSource/SharpZipLib/
[2] http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream(VS.80).aspx

Unless its been rewritten, DeflateStream is larger and over 20% slower than the ICSharpCode equivalent which is the reason I still use it. - mythz
hidden features from c# because none of these are features of c#? - sehe
208
[+6] [2010-01-10 01:27:07] Jamie Keeling

I find the use of the conditional break function in Visual Studio very useful. I like the way it allows me to set the value to something that, for example can only be met in rare occasions and from there I can examine the code further.


209
[+6] [2010-05-02 13:17:49] Navid Farhadi

This means T must have a public parameterless constructor :

 class MyClass<T> where T : new()
 {

 }

(1) So you can new() it in the implementation. - riezebosch
210
[+6] [2010-07-06 19:52:37] AaronLS

Accessing local variables from anonymous methods allows you to wrap just about any code with new control flow logic, without having to factor out that code into another method. Local variables declared outside the method are available inside the method such as the endOfLineChar local variable in the example here:

http://aaronls.wordpress.com/2010/02/02/retrying-on-exception-conditionally/


211
[+5] [2008-08-25 14:21:57] John Boker

@lainMH,

Nullable booleans are useful when retrieving values from a database that are nullable and when putting values back in. Sometimes you want to know the field has not been set.


212
[+5] [2008-08-26 18:51:13] Drakiula

Reflection Emit and Expression trees come to mind...

Don't miss Jeffrey Richter's CLR via C# and Jon Skeet's alt text

See here for some resources:

http://www.codeproject.com/KB/trace/releasemodebreakpoint.aspx

http://www.codeproject.com/KB/dotnet/Creating_Dynamic_Types.aspx

http://www.codeproject.com/KB/cs/lambdaexpressions.aspx


213
[+5] [2008-09-16 14:43:44] Thomas Danecker

System.Runtime.Remoting.Proxies.RealProxy [1]

It enables Aspect Oriented Programming in C#, and you can also do a lot of other fancy stuff with it.

[1] http://msdn.microsoft.com/en-us/library/system.runtime.remoting.proxies.realproxy.aspx

How do you get AOP from something that "supports remoting infastructure"? - Qwertie
Because it supports the remoting infrastructure by enabling AOP ;) Look here for the technical aspects of it: tdanecker.blogspot.com/2007/09/interception-with-proxies.htm‌​l - Thomas Danecker
214
[+5] [2008-10-12 04:26:32] sbeskur

I find this technique interesting while working with linqxml:

public bool GetFooSetting(XElement ndef){
   return (bool?)ndef.Element("MyBoolSettingValue") ?? true;
}

as opposed to:

public bool GetFooSetting(XElement ndef){
   return ndef.Element("MyBoolSettingValue") != null ? bool.Parse(ndef.Element("MyBoolSettingValue") ) : true;
}

215
[+5] [2008-11-03 15:26:12] Johan S

The generic event handler:

public event EventHandler<MyEventArgs> MyEvent;

This way you don't have to declare your own delegates all the time,


216
[+5] [2008-11-03 16:16:07] Gavin Miller

I didn't discover - for almost a year - that Strongly Typed DataRows contain an Is[ColumnName]Null() method.

For example:

Units.UnitsDataTable dataTable = new Units.UnitsDataTable();

foreach (Units.UnitsRow row in dataTable.Rows)
{
    if (row.IsPrimaryKeyNull())
        //....

    if (row.IsForeignKeyNull())
        //....
}

(3) To be nitpicky, it's not a C# feature, it's a .NET feature ;) - LBugnion
217
[+5] [2009-03-12 08:46:23] kentaromiura

Is constructor chain already cited?

namespace constructorChain {
    using System;

    public class Class1 {
        public string x;
        public string y;

        public Class1() {
            x = "class1";
            y = "";
        }

        public Class1(string y)
            : this() {
            this.y = y;
        }
    }

    public class Class2 : Class1 {
        public Class2(int y)
            : base(y.ToString()) {

        }
    }
}

...

        constructorChain.Class1 c1 = new constructorChain.Class1();
        constructorChain.Class1 c12 = new constructorChain.Class1("Hello, Constructor!");
        constructorChain.Class2 c2 = new constructorChain.Class2(10);
        Console.WriteLine("{0}:{1}", c1.x, c1.y);
        Console.WriteLine("{0}:{1}", c12.x, c12.y);
        Console.WriteLine("{0}:{1}", c2.x, c2.y);

        Console.ReadLine();

when can this be useful? - Peter Gfader
(3) Everytime you have constructors that contains the same initialization code, constructor chaining avoids code duplication. - kentaromiura
218
[+5] [2009-04-23 12:57:48] Akash Kava

FIXED / Power of Pointers in C# - This topic is too big, but I will just outline simple things.

In C we had facility of loading structure like...

struct cType{
   char type[4];
   int  size;
   char name[50];
   char email[100];
}

cType myType;
fread(file, &mType, sizeof(mType));

We can use fixed keyword in "unsafe" method to read byte array aligned structure.

[Layout(LayoutKind.Sequential, Pack=1)]
public unsafe class CType{
    public fixed byte type[4];
    public int size;
    public fixed byte name[50];
    public fixed byte email[100];
}

Method 1 (Reading from regular stream in to byte buffer and mapping byte array to individual bytes of struct)

CType mType = new CType();
byte[] buffer = new byte[Marshal.SizeOf(CType)];
stream.Read(buffer,0,buffer.Length);
// you can map your buffer back to your struct...
fixed(CType* sp = &mType)
{
    byte* bsp = (byte*) sp;
    fixed(byte* bp = &buffer)
    {
         for(int i=0;i<buffer.Length;i++)
         {
             (*bsp) = (*bp);
             bsp++;bp++;
         }
    }
}

Method 2, you can map Win32 User32.dll's ReadFile to directly read bytes...

CType mType = new CType();
fixed(CType* p = &mType)
{
    User32.ReadFile(fileHandle, (byte*) p, Marshal.SizeOf(mType),0);
}

219
[+5] [2009-07-16 05:16:29] David.Chu.ca

I like to use the using directive to rename some classes for easy reading like this:

// defines a descriptive name for a complexed data type
using MyDomainClassList = System.Collections.Generic.List<
  MyProjectNameSpace.MyDomainClass>;

....


MyDomainClassList myList = new MyDomainClassList();
/* instead of 
List<MyDomainClass> myList = new List<MyDomainClass>();
*/

This is also very handy for code maintenance. If you need to change the class name, there is only one place you need to change. Another example:

using FloatValue  = float; // you only need to change it once to decimal, double...

....
FloatValue val1;
...

220
[+5] [2009-07-27 00:43:31] Paul van Brenk

Zero parameter Lambdas

()=>Console.ReadLine()

(1) Needs explanation of where you'd use this. - Ryan Lundy
As an argument to any method that takes an Action delegate parameter. In C# 2.0 you would use delegate { Console.ReadLine() } instead. - Christian Hayter
Also useful when coupled with Expression trees parsing :) - chakrit
221
[+5] [2009-07-30 03:57:06] ccook

I didn't see this:

for (;;);

The same as

while (true) ;

222
[+5] [2009-08-23 11:07:06] mezoid

One that I just learned recently is that you can still call methods on a nullable value [1]....

It turns out what when you have a nullable value:

decimal? MyValue = null;

where you might think you would have to write:

MyValue == null ? null : MyValue .ToString()

you can instead write:

MyValue.ToString()

I've been aware that I could call MyValue.HasValue and MyValue.Value...but it didn't fully click that I could call ToString().

[1] https://stackoverflow.com/questions/1242883/is-there-a-better-way-to-write-this-line-of-c-code-in-c3-0

223
[+5] [2009-09-03 03:36:51] manji

This will not compile:

namespace ns
{
    class Class1
    {
        Nullable<int> a;
    }
}

The type or namespace name 'Nullable' could not be found (are you missing a using directive or an assembly reference?) <-- missing 'using System;'

But

namespace ns
{
    class Class1
    {
        int? a;
    }
}

will compile! (.NET 2.0).


(1) belongs in strangest corner cases (stackoverflow.com/questions/194484/…) but +1 anyway - RCIX
Maybe it will directly convert int? to System.Nullable<System.Int32> so that is the reason it works fine? - devoured elysium
This is really the same as int vs Int32. - MattDavey
224
[+5] [2009-09-11 03:52:09] Todd Richardson

I apologize if this one has been mentioned, but I use this a lot.

An add-in for Visual Studio was developed by Alex Papadimoulis. It's used for pasting regular text as string, string builder, comment or region.

http://weblogs.asp.net/alex_papadimoulis/archive/2004/05/25/Smart-Paster-1.1-Add-In---StringBuilder-and-Better-C_2300_-Handling.aspx

In this plugin (I also don't know if this has been mentioned) I noticed that strings are pasted with the string literal prefix:

@

I knew about these, but I didn't know about using a double quote within a literal to escape the quote.

For example

string s = "A line of text" + Environment.NewLine + "Another with a \"quote\"!!";

can be expressed as

string s = @"A line of text 
Another with a ""quote""!!";

I'm sure it's been posted before and it's not exactly a hidden feature, but I didn't know about the newline this way. - Vivelin
225
[+5] [2009-11-21 08:12:56] Brian

I like the EditorBrowsableAttribute [1]. It lets you control whether a method/property is displayed or not in Intellisense. You can set the values to Always, Advanced, or Never.

From MSDN [2]...

Remarks

EditorBrowsableAttribute is a hint to a designer indicating whether a property or method is to be displayed. You can use this type in a visual designer or text editor to determine what is visible to the user. For example, the IntelliSense engine in Visual Studio uses this attribute to determine whether to show a property or method.

In Visual C#, you can control when advanced properties appear in IntelliSense and the Properties Window with the Hide Advanced Members setting under Tools | Options | Text Editor | C#. The corresponding EditorBrowsableState is Advanced.

[1] http://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute.aspx
[2] http://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute.aspx

(1) Using this attribute is often annoying, though. Use it where you have a member on a class due to the inheritance structure, but the member is intentionally unimplemented. But don't hide members that are just "not recommended for use". If there's any legitimate scenario for using the member, leave it visible. A particularly annoying case is TreeView.Sorted ( msdn.microsoft.com/en-us/library/… ), where the Sorted property has functionality but is still hidden for some strange reason. - Ryan Lundy
226
[+5] [2009-12-03 00:45:50] Zac Bowling

__arglist as well

[DllImport("msvcrt40.dll")]
public static extern int printf(string format, __arglist);

static void Main(string[] args)
{
   printf("Hello %s!\n", __arglist("Bart"));
}

(1) +1 for the "secret" google==>community.bartdesmet.net/blogs/bart/archive/2006/09‌​/28/… - Behrooz
227
[+5] [2009-12-25 21:33:48] Dave Jellison

The Action and Func delegate helpers in conjunction with lambda methods. I use these for simple patterns that need a delegate to improve readability. For example, a simple caching pattern would be to check if the requested object exists in the cache. If it does exist: return the cached object. If it doesn't exist, generate a new instance, cache the new instance and return the new instance. Rather that write this code 1000 times for each object I may store/retrieve from the cache I can write a simple pattern method like so...

private static T CachePattern<T>(string key, Func<T> create) where T : class
{
    if (cache[key] == null)
    {
        cache.Add(key, create());
    }

    return cache[key] as T;
}

... then I can greatly simplify my cache get/set code by using the following in my custom cache manager

public static IUser CurrentUser
{
    get
    {
        return CachePattern<IUser>("CurrentUserKey", () => repository.NewUpUser());
    }
}

Now simple "everyday" code patterns can be written once and reused much more easily IMHO. I don't have to go write a delegate type and figure out how I want to implement a callback, etc. If I can write it in 10 seconds I'm much less apt. to resort to cutting/pasting simple code patterns whether they be lazy initialization and some other examples shown above...


Nice one! We have something similar, but with the TimeSpan and CacheItemPriority as a parameter as well! We are using ASP.NET cache. - Peter Gfader
228
[+5] [2010-03-08 22:43:57] Anthony Mastrean

Empty blocks with braces are allowed.

You can write code like this

{
    service.DoTonsOfWork(args);
}

It's helpful when you want to try something without a using or try... finally that you've already written.

//using(var scope = new TransactionScope)
{
    service.DoTonsOfWork(args);
}

(2) It's also handy as a visual indicator of other types of nesting; for instance, I often use braces to nest the statements between a Debug.Indent() and a Debug.Unindent. - Ryan Lundy
(2) they are useful for limiting the scope of a variable - bohdan_trotsenko
229
[+5] [2010-04-05 11:15:10] Anemoia

Nullable.GetValueOrDefault ?


(1) or the ?? operator for nullable types. - John Alexiou
230
[+4] [2008-08-24 22:10:22] Haacked

One interesting thing I've learned is that different parts of the framework and C# language were written at different times, hence inconsistencies. For example, the framework itself violates many FxCop rules because the rules weren't all in place when the framework was written.

Also, the using statement was intended for delinieating "scopes" and not specifically for disposing resources. It was written after the lock statement. Eric Gunnerson once mentioned [1] something along the lines of that if the using statement came first, they might have not needed to write the lock statement (though who knows, maybe they would have anyways), because the using statement might have been sufficient.

[1] http://haacked.com/archive/2004/05/27/DifficultiesOfLanguageDesign.aspx

231
[+4] [2008-09-03 15:03:20] Michael Prewecki

TryParse method for each primitive type is great when validating user input.

double doubleValue
if (!Double.TryParse(myDataRow("myColumn"), out doubleValue))
{
    // set validation error
}

I see I'm not the only one who forgets the "out" modifyer. - Jeffrey L Whitledge
doens't that return a bool? and set with an 'out' keyword? - Nicholas Mancuso
232
[+4] [2008-09-19 05:18:35] Statement

The #region {string} and #endregion pair is very neat for grouping code (outlining).

#region Using statements
using System;
using System.IO;
using ....;
using ....;
#endregion

The code block can be compressed to a single describing line of text. Works inside functions aswell.


(2) I suppose it's a matter of preference, but when I'm looking at source code I'd rather not have to be expanding hidden sections of code. Regions used sparingly (outside of methods) aren't an issue, but beware using them in lieu of writing readable/maintainable code in the first place. - J c
I quite like regions but some people overuse them. I couldn't agree with you more about keeping them out of methods. I have seen the whole purpose of a method obfuscated by a region that was collapsed by default but that a colleague had accidentally hidden a key variable change within. - BlackWasp
(1) I agree with not using regions inside methods. By the way, Ctrl-M, Ctrl-L will expand all the regions in Visual Studio - LBugnion
(1) Basically, whenever I feel a need for regions inside a method, that region is often better suited as a method call of its own instead. - Statement
Some forms have a lot of controls, with a lot of controls comes a lot of event handlers, seems like a good place to use regions. Event code vs. event called or non-event code. - Maslow
(1) But isn't a #region around the using directives redundant? They're still collapsible without it. - TheBeardyMan
(1) People are still using regions? Regions are a code smell: morten.lyhr.dk/2008/07/… - Chuck Conway
233
[+4] [2008-09-20 01:50:13] Ray Lu

I think a lot of people know about pointers in C but are not sure if it works in C#. You can use pointers in C# in an unsafe context:

static void Main()
{
    int i;
    unsafe
    {               
        // pointer pi has the address of variable i
        int* pi = &i; 
        // pointer ppi has the address of variable pi
        int** ppi = &pi;
        // ppi(addess of pi) -> pi(addess of i) -> i(0)
        i = 0;
        // dereference the pi, i.e. *pi is i
        Console.WriteLine("i = {0}", *pi); // output: i = 0
        // since *pi is i, equivalent to i++
        (*pi)++;
        Console.WriteLine("i = {0}", *pi); // output: i = 1
        // since *ppi is pi, one more dereference  *pi is i 
        // equivalent to i += 2
        **ppi += 2;
        Console.WriteLine("i = {0}", *pi);// output: i = 3
    }
    Console.ReadLine();
}

234
[+4] [2008-10-21 19:08:37] Ian Andrews

This may be pretty basic to database application developers, but it took me a while to realize that null is not the same as DBNull.value.

You have to use DBNull.value when you want to see if a value from a database record is null.


235
[+4] [2008-11-03 15:42:24] Dan Fleet

Just learned the joys of [UnmanagedFunctionPointerAttribute(CallingConvention.CDecl)] from trying to interface with an unmanaged C++ function library that defined callbacks without __stdcall.


236
[+4] [2008-11-23 17:45:14] Gregor

Framework Feature

I don't know but I was quite suprised about VisualStyleRenderer [1] and the whole System.Windows.Forms.VisualStyles-Namespace [2]. Pretty cool!

[1] http://msdn.microsoft.com/de-de/library/system.windows.forms.visualstyles.visualstylerenderer(VS.85).aspx
[2] http://msdn.microsoft.com/de-de/library/system.windows.forms.visualstyles(VS.85).aspx

237
[+4] [2009-04-27 16:46:52] Dries Van Hansewijck

The InternalsVisibleToAttribute specifies that types that are ordinarily visible only within the current assembly are visible to another assembly. Article on msdn [1]

[1] http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

238
[+4] [2009-06-05 20:56:00] Kevin Doyon

If you have the search textbox in your Visual Studio toolbar, you can type ">of Program.cs" to open the file Program.cs


It's a Visual Studio feature, not a C# feature - Thomas Levesque
So are snippets, but they are in the main post under "Visual Studio Features". - Kevin Doyon
239
[+4] [2009-06-14 16:11:16] zebrabox

A few from me - make of them what you will.

The attribute:

[assembly::InternalsVisibleTo("SomeAssembly")]

Allows you to expose out the internal methods/properties or data from your assembly to another assembly called 'SomeAssembly'. All protected/private stuff remains hidden.


Static constructors ( otherwise called 'Type Constructor' )

public MyClass
{
  public static MyClass()
  {
     // type init goes here
  }
  ......
}  

The keyword internal. So useful in so many ways.


240
[+4] [2009-06-16 18:38:22] epitka

Ability to create instance of the type based on the generic parameter like this

new T();


(1) Requires the "where T : new()" constraint. - sisve
241
[+4] [2009-06-22 12:29:48] Paul Ruane

Marketing events as non-serializable:

[field:NonSerializable]
public event SomeDelegate SomeEvent;

242
[+4] [2009-06-30 07:11:12] Michael Erasmus

Generic constraints:

 //Constructor constraint, T has a default empty constructor
class Node<K,T> where T : new() 
{
}

//Reference\Value Type constraints
//T is a struct
public class MyClass<T> where T : struct 

{...}

//T is a reference type
public class MyClass<T> where T : class 

{...}

public class MyClass<T> where T : SomeBaseClass, ISomeInterface 

{...}

243
[+4] [2009-07-21 21:46:11] Dan Diplo

How about Expression Trees [1]? They are the heart of LINQ and allow for defered execution:

Taken from David Hayden's blog [2]:

In C# 3.0, you can define a delegate as follows using a lambda expression:

Func<int,int> f = x => x + 1;

This delegate is compiled into executable code in your application and can be called as such:

var three = f(2); // 2 + 1

The code works as you would expect. Nothing fancy here.

Expression Trees

When you define the delegate as an Expression Tree by using System.Query.Expression:

Expression<Func<int,int>> expression = x => x + 1;

The delegate is no longer compiled into executable code, but compiled as data that can be converted and compiled into the original delegate.

To actually use the delegate represented as an Expression Tree in your application, you would have to compile and invoke it in your application:

var originalDelegate = expression.Compile();

var three = originalDelegate.Invoke(2);
[1] http://msdn.microsoft.com/en-us/library/bb397951.aspx
[2] http://www.davidhayden.com/blog/dave/archive/2006/12/18/ExpressionTrees.aspx

244
[+4] [2009-08-05 17:01:19] John Leidegren

A lot of this is explained already, in the standard [1]. It's a good read for any beginner as well as expert, it's a lot to read, but it's the official standard, and it's filled with juicy details.

Once you fully understand C#, it's time to take this further to understand the fundamentals of the Common Language Infrastructure [2]. The architecture and underpinnings of C#.

I've met a variety of programmers that don't know the difference between an object and a ValueType except the adherent limitations thereof.

Familiarize yourself with these two documents and you'll never become that person.

[1] http://www.ecma-international.org/publications/standards/Ecma-334.htm
[2] http://www.ecma-international.org/publications/standards/Ecma-335.htm

245
[+4] [2009-08-07 22:39:32] paracycle

Generics and the Curiously-Recurring Template Pattern [1] really help with some static method/property declarations.

Suppose you are building a class hierarchy:

class Base
{
}

class Foo: Base
{
}

class Bar: Base
{
}

Now, you want to declare static methods on your types that should take parameters (or return values) of the same type or static properties of the same type. For example, you want:

class Base
{
    public static Base Get()
    {
        // Return a suitable Base.
    }
}

class Foo: Base
{
    public static Foo Get()
    {
        // Return a suitable Foo.
    }
}

class Bar: Base
{
    public static Bar Get()
    {
        // Return a suitable Bar.
    }
}

If these static methods basically all do the same thing, then you have lots of duplicated code on your hands. One solution would be to drop type safety on the return values and to always return type Base. However, if you want type safety, then the solution is to declare the Base as:

class Base<T> where T: Base<T>
{
    public static T Get<T>()
    {
        // Return a suitable T.
    }
}

and you Foo and Bar as:

class Foo: Base<Foo>
{
}

class Bar: Base<Bar>
{
}

This way, they will automatically get their copies of the static methods.

This also works wonders to encapsulate the Singleton pattern in a base class (I know the code below is not thread-safe, it just to demonstrate a point):

public class Singleton<T> where T: Singleton<T>, new()
{
  public static T Instance { get; private set; }

  static Singleton<T>()
  {
    Instance = new T();
  }
}

I realize that this forces you to have a public parameterless constructor on your singleton subclass but there is no way to avoid that at compile time without a where T: protected new() construct; however one can use reflection [2] to invoke the protected/private parameterless constructor of the sub-class at runtime to achieve that.

[1] http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
[2] http://www.codeproject.com/KB/architecture/GenericSingletonPattern.aspx

I think reflection is the best option here... Performance is not really important in that case, because the constructor will only be called once, and having a public constructor on a singleton type is just plain wrong. - Thomas Levesque
Oh yes, I totally agree. Reflection for protected constructors in the Singleton base class is what I have working in my code. However, I didn't what to pollute the example with all the reflection code. - paracycle
Yup, that's a good example of why you want to use the "infinite interface" as i call it - RCIX
Be aware that any class derived from Foo or Bar will have a static Get that returns either Foo or Bar and not the type of the derived class you're calling upon, whether the derived class is passing its own type to Foo (or Bar respectively) or not. In short: the recurrance only goes one level deep which is not very intuitive to anyone who builds upon your classes. - Sandor Drieënhuizen
(1) Why not just protected abstract T CreateInstance() forcing the child class to override that and then in Instance property you'd call the method if there's Instance == null ? - chakrit
(1) It's answers to questions like this that makes me wish I could "Favorite" an answer. - Pretzel
(1) @Pretzel - I agree that a proper "Favorite" option would be much better, but I have managed to use up-votes to achieve something similar. You can always up-vote the answer you like and when you later go over the stuff that you have up-voted, you end up finding your "Favorite"s. - paracycle
246
[+4] [2009-10-26 16:45:31] Florian Doyon

I love abusing the fact that static templated classes don't share their static members.

Here's a threadsafe (at creation time) and cheap substitute to any Dictionary<Type,...> when the Type instance is known at compile-time.

public static class MyCachedData<T>{
    static readonly CachedData Value;
    static MyCachedData(){
       Value=// Heavy computation, such as baking IL code or doing lots of reflection on a type
    }
}

Cheers, Florian


a substitute to 'any Dictionary'? How? Care to explain? - sehe
hi, looks like my edit was cut... Should read "substitute to any dictionary taking a type as its key when the type is known at compile time" - fixed the original post (used backtick to escape brackets) - Florian Doyon
247
[+4] [2009-11-25 17:16:48] Phillip Ngan

Convert enum values to a string value

Given the enum

enum Country
{
    UnitedKingdom, 
    UnitedStates,
    UnitedArabEmirates,
}

using it:

public static void PrintEnumAsString( Country country )
{
    Console.Writeline( country.ToString() );
}

will print the name of the enum value as a string, e.g. "UnitedKingdom"


(9) It's not a trick or even a hidden feature of C# or .NET at all. - Lyubomyr Shaydariv
248
[+4] [2010-01-07 15:57:15] iChaib
  • Attaching ? to a Type to make it nullable, ex: int?
  • "c:\dir" instead of @"C:\dir"

exactly I mean "d:\\" (that's the correct form), but generally people want to write directly "d:\" but they're obliged to use \\, instead of that they could use verbatim strings - iChaib
249
[+4] [2010-02-02 22:12:39] murki

I just want to mention (because of the OP metioning where T : struct) that one of the C# compiler gotchas is that

where T : Enum

will NOT compile. It throws the error "Constraint cannot be special class 'System.Enum'".


Though, I bet where T : System.Enum, with a captial E will. - John Leidegren
Oh John, I actually meant that System.Enum won't compile. Changed my answer to caps now. - murki
250
[+4] [2010-02-09 19:05:23] Max Toro

Collection Initializer inside Object Initializer:

MailMessage mail = new MailMessage {
   To = { new MailAddress("a@example.com"), new MailAddress("b@example.com") },
   Subject = "Password Recovery"
};

You can initialize a whole tree in a single expression.


just don't do this in a using clause - Maslow
251
[+4] [2010-02-11 10:37:59] Mubashar

I am bit late in this conversation and I would like to contribute the following. It may be a new thing for some developers.

public class User
{
    public long UserId { get; set; }
    public String Name { get; set; }
    public String Password { get; set; }
    public String Email { get; set; }
}

The usual way to declare and initialize it is with a constructor or like following.

User user = new User();
user.UserId = 1;
user.Name = "myname";
etc

But I learned following way to initialize it. I know Visual Basic developers will love it because it's like with operator available only in VB.NET and not in C# that is as follows.

User user = new User()
{
    UserId = 1,
    Name = "myname",
    Email = "myemail@domain.com",
    Password = "mypassword"
};

Have a look at the answer right below yours – this has already been posted (more than once, I think). - Konrad Rudolph
:) Yes but its above my answer, but it wasn't in summary so i contributed. - Mubashar
csharp 3.5 contains this operator too, and you can use autoperties at examples - Avram
(1) this operator <> with operator ... With are wayyy more awesome :) - chakrit
252
[+4] [2010-03-11 15:01:42] Silviu

One of the most useful features Visual Studio has is "Make object id". It generates an id and "attaches" to the object so wherever you look at the object you will also see the id (regardless of the thread).

While debugging right click on the variable tooltip and there you have it. It also works on watched/autos/locals variables.


253
[+4] [2010-04-05 03:58:57] Joshua Rodgers

This relates to static constructors. This is a method for performing static destruction (i.e. cleaning up resources when the program quits).

First off the class:

class StaticDestructor
{
    /// <summary>
    /// The delegate that is invoked when the destructor is called.
    /// </summary>
    public delegate void Handler();
    private Handler doDestroy;

    /// <summary>
    /// Creates a new static destructor with the specified delegate to handle the destruction.
    /// </summary>
    /// <param name="method">The delegate that will handle destruction.</param>
    public StaticDestructor(Handler method)
    {
        doDestroy = method;
    }

    ~StaticDestructor()
    {
        doDestroy();
    }
}

Then as a member of the class you wish to have a "static destructor" do:

private static readonly StaticDestructor destructor = new StaticDestructor
(
    delegate()
    {
        //Cleanup here
    }
);

This will now be called when final garbage collection occurs. This is useful if you absolutely need to free up certain resources.

A quick and dirty program exhibiting this behavior:

using System;

namespace TestStaticDestructor
{
    class StaticDestructor
    {
        public delegate void Handler();
        private Handler doDestroy;

        public StaticDestructor(Handler method)
        {
            doDestroy = method;
        }

        ~StaticDestructor()
        {
            doDestroy();
        }
    }

    class SomeClass
    {
        static SomeClass()
        {
            Console.WriteLine("Statically constructed!");
        }

        static readonly StaticDestructor destructor = new StaticDestructor(
            delegate()
            {
                Console.WriteLine("Statically destructed!");
            }
        );
    }

    class Program
    {
        static void Main(string[] args)
        {
            SomeClass someClass = new SomeClass();
            someClass = null;
            System.Threading.Thread.Sleep(1000);
        }
    }
}

When the program exits, the "static destructor" is called.


Simply make sure that all statically 'constructed' references are IDisposable? If you needed this you should probably look into Constrained Execution Regions, SafeHandles, Critical Finalizers or in general: here Now if you must have the deterministic shutdown sequence you won't get otherwise, you could should just hookup your custom shutdown handlers to the same event you are using in your own sample, but rely on the IDisposable's again. Also go look here - sehe
IDisposable is not guaranteed to have Dispose() called unless you include a finalizer to call it. Even in that case, there might be some underlying code you must call during shutdown (i.e. a call to an unmanaged library to clean itself up). That's to say you don't have a direct handle to the resources you wish to clean up, because the library you're using maintains those; however, SafeHandles can also do that for you. - Joshua Rodgers
254
[+4] [2010-06-22 19:57:59] STW

I don't condone it, but I was surprised that goto [1] is still around ducks incoming projectiles

[1] http://msdn.microsoft.com/en-us/library/13940fs2(VS.100).aspx

(6) I use goto on occasion. There is nothing wrong with it. - ChaosPandion
(8) @ChaosPandion watch out for Velociraptors xkcd.com/292 - STW
(6) Since the switch construct in C# no longer allows case fall-through, the goto statement is the only thing that you have to pass control onto another case statement, just like it says in the documentation that you link to. Hidden? Perhaps. Wrong? Absolutely not. - Dave Van den Eynde
(1) @Chaos: Key word: "on occasion". - bobobobo
Of course by "no longer" I didn't mean to imply that C# once did, but merely referenced to its ancestry. - Dave Van den Eynde
Remember that we also need to support codes/algorithms written in the early days, containing goto, or transfer them from C/C++. You don't want to change a bit of such codes, and that is a reason for the existence of the "goto" keyword. - ileon
@ileon a good point; personally my favorite use of goto to is knock down C# developers down a notch when they get elitist against VB.NET--I code both, so I have to have ammo that goes both ways :D - STW
goto is for those rare circumstances where you can't jump out of a control structure cleanly any other way. - David R Tribble
@Dave Van den Eynde: case fall-through is dangerous, that's why (I suppose) it is not allowed in C#. So I don't think using goto in those cases is the best thing to do. - Arseni Mourzenko
Case fall-through is dangerous because it can be easily overlooked when reading code. Explicitly demanding goto is the best thing that happened to C#. - Dave Van den Eynde
255
[+4] [2012-02-23 12:34:19] Laradda

You can combine the protected and internal accessor to make it public within the same assembly, but protected in a diffrent assembly. This can be used on fields, properties, method and even constants.


256
[+3] [2008-08-28 14:49:03] nemoby

Returning IQueryable projections

protected void LdsPostings_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{   
    var dc = new MyDataContext();
    var query = dc.Posting.AsQueryable();

    if (isCondition1)
    {
        query = query.Where(q => q.PostedBy == Username);
        e.Result = QueryProjection(query);
        return;
    }

    ...

    if (isConditionN)
    {
        query = query.Where(q => q.Status.StatusName == "submitted");
        query = query.Where(q => q.ReviewedBy == Username);
        e.Result = QueryProjection(query);
        return;
    }
}

and rather than coding the projection multiple times, create a single method:

private IQueryable QueryProjection(IQueryable<Posting> query)
{
    return query.Select(p => new
    {
        p.PostingID,
        p.Category.CategoryName,
        p.Type.TypeName,
        p.Status.StatusName,
        p.Description,
        p.Updated,
        p.PostedBy,
        p.ReviewedBy,
    });
}

257
[+3] [2008-10-09 20:37:13] Scott McKenzie

ContextBoundObject

Not so much a C# thing as a .NET thing. It's another way of achieving DI although it can be hardwork. And you have to inherit from it which can be off putting.

http://msdn.microsoft.com/en-us/library/system.contextboundobject.aspx

I've used it to add logging when I decorate a class/method with a custom logging attribute.


258
[+3] [2008-10-13 22:29:09] Jan Bannister
double dSqrd = Math.Pow(d,2.0); 

is more accurate than

double dSqrd = d * d; // Here we can lose precision

Care to give an example? (Note that there's always the possibility of losing precision...) - Jon Skeet
259
[+3] [2008-11-01 19:48:28] dviljoen

ThreadStaticAttribute is a favorite of mine. Also, NonSerializableAttribute is useful. (Can you tell I do a lot of server stuff using remoting?)


260
[+3] [2008-11-15 07:14:26] Bryan Watts

ViewState getters can be one-liners.

Using a default value:

public string Caption
{
    get { return (string) (ViewState["Caption"] ?? "Foo"); }
    set { ViewState["Caption"] = value; }
}

public int Index
{
    get { return (int) (ViewState["Index"] ?? 0); }
    set { ViewState["Index"] = value; }
}

Using null as the default:

public string Caption
{
    get { return (string) ViewState["Caption"]; }
    set { ViewState["Caption"] = value; }
}

public int? Index
{
    get { return (int?) ViewState["Index"]; }
    set { ViewState["Index"] = value; }
}

This works for anything backed by a dictionary.


261
[+3] [2009-02-03 18:42:13] Rene Stein

Only for reference - enum binary operations using the extension method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace BinaryOpGenericTest
{
    [Flags]
    enum MyFlags
    {
        A = 1,
        B = 2,
        C = 4

    }

    static class EnumExtensions
    {
        private static Dictionary<Type, Delegate> m_operations = new Dictionary<Type, Delegate>();

        public static bool IsFlagSet<T>(this T firstOperand, T secondOperand) 
                                                  where T : struct
        {

            Type enumType = typeof(T);


            if (!enumType.IsEnum)
            {
                throw new InvalidOperationException("Enum type parameter required");
            }


            Delegate funcImplementorBase = null;
            m_operations.TryGetValue(enumType, out funcImplementorBase);

            Func<T, T, bool> funcImplementor = funcImplementorBase as Func<T, T, bool>;

            if (funcImplementor == null)
            {
                funcImplementor = buildFuncImplementor(secondOperand);
            }



            return funcImplementor(firstOperand, secondOperand);
        }


        private static Func<T, T, bool> buildFuncImplementor<T>(T val)
                                                            where T : struct
        {
            var first = Expression.Parameter(val.GetType(), "first");
            var second = Expression.Parameter(val.GetType(), "second");

            Expression convertSecondExpresion = Expression.Convert(second, typeof(int));
            var andOperator = Expression.Lambda<Func<T, T, bool>>(Expression.Equal(
                                                                                                       Expression.And(
                                                                                                            Expression.Convert(first, typeof(int)),
                                                                                                             convertSecondExpresion),
                                                                                                       convertSecondExpresion),
                                                                                             new[] { first, second });
            Func<T, T, bool> andOperatorFunc = andOperator.Compile();
            m_operations[typeof(T)] = andOperatorFunc;
            return andOperatorFunc;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            MyFlags flag = MyFlags.A | MyFlags.B;

            Console.WriteLine(flag.IsFlagSet(MyFlags.A));            
            Console.WriteLine(EnumExtensions.IsFlagSet(flag, MyFlags.C));
            Console.ReadLine();
        }
    }
}

262
[+3] [2009-05-22 19:28:26] Oorang

Well... Don't use it, but a lot of people don't know C# supports the evil goto:)

static void Example()
{
    int i = 0;
top:
    Console.WriteLine(i.ToString());
    if (i == 0)
    {
        i++;
        goto top;
    }
}

If you use Reflector, you will see that there are quite a lot of gotos in the .NET Framework code... scary ! - Thomas Levesque
@Thomas: Most gotos you see in Reflector are just failures of Reflector to correctly detect the while, do/while, for, etc. originally used. Switch statements, in particular, tend to lead to a bunch of "goto Label_01BE", and the like. If you follow through the logic flow, you can usually determine that the source code was probably better structured. And now that the source code for much of the framework is available (weblogs.asp.net/scottgu/archive/2008/01/16/…), you can see for yourself. - P Daddy
(6) @Oorang: I'd rather see a well-placed goto now and then than more complicated code that tries to avoid it. I've only rarely needed it, and most uses have been of the goto case... variety within a switch statement, but it's good to have it when it's what you need. Goto's inclusion in the language is for those occasional times when it really is the clearest construct, not to be avoided at all costs. - P Daddy
I've found goto quite useful in some console input situations. - Skurmedel
I do use it somethimes you have a function with a final action you don't want to do return in the middle of instead you go to the end, the ret value is declared on top as null - Shimmy Weitzhandler
I'm often a defender of goto (ie breaking out of nested loops) but I'll be honest... That just sounds like a structure that could be improved. - Oorang
263
[+3] [2009-06-04 08:41:48] RCIX

Definitely the Func<> types when used with statement lambdas in .NET 3.5. These allow customizable functions, and can be a great aid in offering user customizable objects without subclassing them or resorting to some limited system like keeping track of a variable that lists what button or key the user wants to monitor. Also, they can be called just like regular methods and can be assigned like variables. The only downside that I can think of is that you're limited to 5 arguments! Although by that point you might want to consider a different solution... Edit: Providing some examples.

...
public Func<InputHelper, float> _horizontalCameraMovement = (InputHelper input) => 
{
    return (input.LeftStickPosition.X * _moveRate) * _zoom;
}
public Func<InputHelper, float> _verticalCameraMovement = (InputHelper input) => 
{
    return (-input.LeftStickPosition.Y * _moveRate) * _zoom;
}
...
public void Update(InputHelper input)
{
    ...
    position += new Vector2(_horizontalCameraMovement(input), _verticalCameraMovement(input));
    ...
}

In this example, you can write a function that does arbitrary calculation and returns a float that will determine the amount that the camera moves by. Not the best code but it gets the point across.

private int foo;
public int FooProperty {
    get
    {
        if (_onFooGotten() == true)
            return _foo;
    }
    set
    {
        if (onFooSet() == true)
            _foo = value;
    }
}
...
public Func<bool> _onFooGotten = () => 
{
    //do whatever...
    return true;
}
public Func<bool> _onFooSet = () =>
{
    //do whatever...
    return true;
}

This isn't the best example (as I haven't really explored this use yet) but it shows an example of using a lambda function for a quick event raiser without the hassle of delegates. Edit: thought of another one. Nullables! The closest thing C# has to optional parameters.


Well if Func<> is so great, why don't you provide some nice examples? - tuinstoel
For instance, if you have a 2D camera class and you want to allow the user to control exactly how the various aspects of control are handled (like movement or zooming) you can use Funcs. Or if you want a single-subscriber event and don't want to bother with the effort of delegates. Basically anything you can think of that would offer the user more control over your object without having to subclass it. - RCIX
Sometimes you have lots of objects visualized in something like a tree control, and you want different context menus depending on the right-clicked object. I like to put a "Func<object,ContextMenuStrip> MenuProvider" property on such controls. - Wim Coenen
Well optional C# 4 has optional parameters - nawfal
264
[+3] [2009-07-23 19:26:07] Brad

If you are trying to create a comma delimited string from a list of items:

string[] itemList = { "Example 1", "Example 2", "Example 3" };
CommaDelimitedStringCollection commaStr = new CommaDelimitedStringCollection();
commaStr.AddRange(itemList);
//outputs Example 1,Example 2,Example 3

Look here [1] for another example.

[1] http://blog.crowe.co.nz/archive/2007/08/25/c---How-to-create-a-comma-seperated-string-from.aspx

(12) I would do string.Join(",", itemList) - Theo
Cut the cruft: var cdsc = new CommaDelimitedStringCollection { "Example 1", "Example 2", "Example 3" }; (also, string.Join takes the cake) - sehe
Altough I prefer the string.Join I'm quite amazed there is a specialized collection in the BCL for this. - riezebosch
265
[+3] [2009-08-14 20:53:32] Maslow

Keeps DataGridView from showing the property:

[System.ComponentModel.Browsable(false)]
public String LastActionID{get; private set;}

Lets you set a friendly display for components (like a DataGrid or DataGridView):

[System.ComponentModel.DisplayName("Last Action")]
public String LastAction{get; private set;}

For your backing variables, if you don't want anything accessing them directly this makes it tougher:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    private DataController p_dataSources;

266
[+3] [2009-09-10 11:21:28] madcyree

At first - DebuggerTypeProxy [1].

[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable : Hashtable
{
    private const string TestString = 
        "This should not appear in the debug window.";

    internal class HashtableDebugView
    {
        private Hashtable hashtable;
        public const string TestStringProxy = 
            "This should appear in the debug window.";

        // The constructor for the type proxy class must have a 
        // constructor that takes the target type as a parameter.
        public HashtableDebugView(Hashtable hashtable)
        {
            this.hashtable = hashtable;
        }
    }
}

At second:

ICustomTypeDescriptor [2]

[1] http://msdn.microsoft.com/en-us/library/d8eyd8zc.aspx
[2] http://msdn.microsoft.com/en-us/library/ms171819.aspx

267
[+3] [2009-10-29 23:44:23] Lyubomyr Shaydariv

The following one is not hidden, but it's quite implicit. I don't know whether samples like the following one have been published here, and I can't see are there any benefits (probably there are none), but I'll try to show a "weird" code. The following sample simulates for statement via functors in C# (delegates / anonymous delegates [lambdas]) and closures. Other flow statements like if, if/else, while and do/whle are simulated as well, but I'm not sure for switch (perhaps, I'm too lazy :)). I've compacted the sample source code a little to make it more clear.

private static readonly Action EmptyAction = () => { };
private static readonly Func<bool> EmptyCondition = () => { return true; };

private sealed class BreakStatementException : Exception { }
private sealed class ContinueStatementException : Exception { }
private static void Break() { throw new BreakStatementException(); }
private static void Continue() { throw new ContinueStatementException(); }

private static void For(Action init, Func<bool> condition, Action postBlock, Action statement) {
    init = init ?? EmptyAction;
    condition = condition ?? EmptyCondition;
    postBlock = postBlock ?? EmptyAction;
    statement = statement ?? EmptyAction;
    for ( init(); condition(); postBlock() ) {
        try {
            statement();
        } catch ( BreakStatementException ) {
            break;
        } catch ( ContinueStatementException ) {
            continue;
        }
    }
}

private static void Main() {
    int i = 0; // avoiding error "Use of unassigned local variable 'i'" if not using `for` init block
    For(() => i = 0, () => i < 10, () => i++,
        () => {
            if ( i == 5 )
                Continue();
            Console.WriteLine(i);
        }
    );
}

If I'm not wrong, this approach is pretty relative to the functional programming practice. Am I right?


(3) Not really. Functional programming practice doesn't just mean "replace everything with functions"... it's thinking functionally. You're still writing a for loop, an elaborate one. Most of the time you will use recursive implementation when programming functionally as that will allows you to code declaratively instead of imperatively I think you missed that point. - chakrit
@charkit, thank you for comment. Yes, I've realized just the same few months ago and I see that I was somewhat wrong asking this question. However, I wrote some scripts for my Foobar2K player using the simple Tagz language, and I've found that Tagz is closer to the functional programming practice than the sample above (if I am right in this case). - Lyubomyr Shaydariv
Especially the fact that your sample code emphasizes on side-effects (Console.WriteLine) pretty much makes it the anti-thesis of functional programming... - sehe
@sehe, yep, I wrote this sample 1,5 years ago without good understanding of FP concepts. Thanks for the point. ))) - Lyubomyr Shaydariv
Comments like that are mainly to inform passers-by about it, not as criticism per se ;) I hope tidbits like that spark peoples interest when they read it for the first time - sehe
268
[+3] [2009-12-29 21:41:35] Jerod Venema

The "TODO" property and the tasks list

//TODO: [something] 

Adding that to your code (the spacing is important) throws an item in your task list, and double clicking the item will jump you to the appropriate location in your code.


(5) You can also define your own custom tags, I think that most people also use: BUG, FIX, REFACTOR, HACK We also use: - MANUAL for missing documentation hints/changes. - QUESTION for changes or code you want the opinion of the development team before proceeding - RESOURCE if the code is based on a blogpost, article, some document (with the url after it) - Cohen
(1) Actually, it's a Visual Studio feature, C# doesn't take care on such comments or whatever something like this. - Lyubomyr Shaydariv
This question 'supports' Visual Studio features as well. - Arda Xi
269
[+3] [2010-01-05 11:51:22] Ravi Vanapalli

I didn't knew about Generic methods which could help avoid using Method Overloadding. Below are overloaded methods to print int and double numbers.

    private static void printNumbers(int [] intNumbers)
    { 
        foreach(int element in intNumbers)
        {
            Console.WriteLine(element);
        }

    }

    private static void printNumbers(double[] doubleNumbers)
    {
        foreach (double element in doubleNumbers)
        {
            Console.WriteLine(element);
        }
    }

Generic method which help to have one method for both of the above

    private static void printNumbers<E>(E [] Numbers)
    {
        foreach (E element in Numbers)
        {
            Console.WriteLine(element);
        }
    }

270
[+3] [2010-01-13 09:31:52] David Stocking

Don't know if this is a secret per se but I loved the added Enumerable (adds to IEnumerable) class in System.Linq.

http://msdn.microsoft.com/en-us/library/system.linq.enumerable_members.aspx

While the yield keyword is already listed. Iterator blocks are freaking amazing. I used them to build Lists that would be tested to see if they were co-prime. It basically allows you to go though a function that returns values one by one and stop any time.

Oh, I almost forgot the best class in the world when you can't optimize it any more. The BackgroundWorker!!!!

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx


271
[+3] [2010-04-08 19:30:55] k25

With reference to the post w/ perma link " Hidden Features of C#? [1]", there is another way to accomplish the same - indentation / line breaks. Check this out..

XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
xmlWriterSettings.NewLineOnAttributes = true;
xmlWriterSettings.Indent = true;


XmlWriter xml = XmlWriter.Create(@"C:\file.xml", xmlWriterSettings);

// Start writing the data using xml.WriteStartElement(), xml.WriteElementString(...), xml.WriteEndElement() etc

I am not sure whether this is an unknown feature though!

[1] https://stackoverflow.com/questions/9033/hidden-features-of-c/2495330#2495330

A language feature it certainly is not - sehe
272
[+3] [2010-06-09 14:39:44] Centro

Lately I learned about the String.Join method. It is really useful when building strings like columns to select by a query.


(3) That's in the .NET Framework (not in C# itself) and is far from hidden, actually. ;-) - peSHIr
Well, I'm pretty sure that it is more hidden than the String.IsNullOrEmpty method which is not in C# but in the .NET Framework too. In the summary at the beginning there is a lot of stuff not specific to C# but .NET in general. - Centro
Isn't that the same as String.Concat ? - Jack Marchetti
No, it's quite different. For example there's an array of strings and you want to get those strings separated by some character, e.g. by comma like "string1,string2,string3". That's what String.Join is for. - Centro
273
[+2] [2008-08-18 00:10:35] Pat Hermens

I think if you have to use nullable types, it's better to use Nullable<.T> rather than the question mark notation. It makes it eye-achingly obvious that magic is occurring. Not sure why anyone would ever want to use Nullable<.bool> though.

In a VB.NET Web service where the parameter might not be passed through (because the partners request wasn't consistent or reliable), but had to pass validation against the proposed type (Boolean for "if is search request"). Chalk it up to "another demand by management"...

...and yes, I know some people think it's not the right way to do these things, but IsSearchRequest As Nullable(Of Boolean) saved me losing my mind that night!


274
[+2] [2008-08-18 17:06:41] martinlund

I must admit that i'm not sure wether this performs better or worse than the normal ASP.NET repeater onItemDatabound cast code, but anyway here's my 5 cent.

MyObject obj = e.Item.DataItem as MyObject;
if(obj != null)
{
  //Do work
}

275
[+2] [2008-09-02 02:10:06] Eduardo Diaz

PreviousPage property:

"The System.Web.UI.Page representing the page that transferred control to the current page."

It is very useful.


This is not a feature of C#, but rather of the System.Web.UI.Page class. - Jon
276
[+2] [2008-09-05 09:14:04] Mark Ingram

@ Robbie Rocketpants [1]

"but my instincts tell me that this would cut a maximum of two type casts operations down to a maximum of one."

If you do the cast as you were suggesting in example 1 (using is & as), it results in 2 calls to the "is" operator. Because when you do "c = obj as MyClass", first it calls "is" behind the scenes, then if it fails that it simply returns null.

If you do the cast as you were suggesting in example 2,

c = (MyClass)obj

Then this actually performs the "is" operation again, then if it fails that check,it throws an exception (InvalidCastException).

So, if you wanted to do a lightweight dynamic cast, it's best to do the 3rd example you provided:

MyClass c;
if (obj is MyClass)
{
    c = obj as MyClass
}

if (c != null)
{
}

vs

MyClass c = obj as MyClass;

if (c != null)
{
}

You can see which is quicker, more consise and clearer.

[1] https://stackoverflow.com/questions/9033?#9092

277
[+2] [2008-09-09 03:30:49] Thomas H

Saw a mention of List.ForEach above; 2.0 introduced a bevy of predicate-based collection operations - Find, FindAll, Exists, etc. Coupled with anonymous delegates you can almost achieve the simplicity of 3.5's lambda expressions.


278
[+2] [2008-09-19 14:39:16] Rob

Some concurrency utilities in the BCL might qualify as hidden features.

Things like System.Threading.Monitor are used internally by the lock keyword; clearly in C# the lock keyword is preferrable, but sometimes it pays to know how things are done at a lower level; I had to lock in C++/CLI, so I encased a block of code with calls to Monitor.Enter() and Monitor.Exit().


279
[+2] [2008-09-19 16:26:29] William Yeung

Before lambda comes into play, it's anonymous delegate. That could be used for blanket code similar to Ruby's blockgiven. I haven't tested how lambda works though because I want to stick with .NET 2.0 so far.

For example when you want to make sure you remember to close your HTML tags:

MyHtmlWriter writer=new MyHtmlWriter();
writer.writeTag("html", 
  delegate ()
  { 
    writer.writeTag("head", 
       delegate() 
       { 
           writer.writeTag("title"...);
       }
    )
  })

I am sure if lambda is an option, that could yield much cleaner code :)


(1) if you're using VS2008, then use the lambda syntax. It's syntactic sugar not a framework feature. It gets compiled to an anonymous delegate anyway and is just less noisy to read. - Hamish Smith
280
[+2] [2009-05-08 17:43:21] Drew Hoskins

In dealing with interop between C++ and C#, many people don't realize that C++/CLI is a great option.

Say you have a C++ DLL and a C# DLL which depends on the C++ DLL. Often, the easiest technique is to compile some (or all) modules of the C++ DLL with the /clr switch. To have the C# call the C++ DLL is to write managed C++ wrapper classes in the C++ DLL. The C++/CLI classes can call the native C++ code much more seamlessly than C#, because the C++ compiler will automatically generate P/invokes for you, has a library specifically for interop, plus language features for interop like pin_ptr [1]. And it allows managed and native code to coexist within the same binary.

On the C# side, you just call into the DLL as you would any other .NET binary.

[1] http://msdn.microsoft.com/en-us/library/1dz8byfh(VS.80).aspx

281
[+2] [2009-06-03 15:37:49] Jeffrey Hines

Relection is so powerfull when used carefully. I used it in an e-mail templating system. The template manager would be passed an object and the html templates would have embedded fields that referred to Properties that could be retrieved off the passed object using reflection. Worked out very nicely.


282
[+2] [2009-09-12 21:26:06] Oliver

Not sure Microsoft would like this question, especially with so many responses. I'm sure I once heard a Microsoft head say:

a hidden feature is a wasted feature

... or something to that effect.


(3) Hidden features are found by those that care about the fine details. - Razor
283
[+2] [2009-10-20 10:04:34] Himadri

Use of @ before a string that contains escape char. Basically when a physical path is used to assign in a string variable everybody uses '\' where escape character is present in a string.

e.g. string strPath="D:\websites\web1\images\";

But escape characters can be ignored using @ before the string value.

e.g. string strPath=@"D:\websites\web1\images\";


284
[+2] [2010-01-26 19:16:16] devforall

Another way of geting IEnumerable through yield without explicity creating an IEnumerable object

public IEnumerable<Request> SomeMethod(IEnumerable<Request> requests)
{
    foreach (Request request in requests)
       yield return DoSomthing(request);
}

(1) of course the sample is weak, and it is hardly hidden. I'd prefer to write this as requests.Select(DoSomthing) 10 out of 10 times. (Also, edited the sample to fix code errors) - sehe
285
[+2] [2010-02-16 09:58:48] Ruben Bartelink

This trick for calling private methods using Delegate.CreateDelegate [1] is extremely neat.

var subject = new Subject();
var doSomething = (Func<String, String>)
    Delegate.CreateDelegate(typeof(Func<String, String>), subject, "DoSomething");
Console.WriteLine(doSomething("Hello Freggles"));

Here's a context where it's useful [2]

[1] http://elegantcode.com/2010/01/28/calling-non-public-methods/
[2] https://stackoverflow.com/questions/1043899/non-code-generated-forwarding-shim-for-testing-private-methods/1804696#1804696

286
[+2] [2010-03-02 05:16:54] Dax70

Most of the P/Invoke [1] stuff is a bit strange.

Example of attributes:

[DllImport ("gdi32.dll")] 
[return : MarshalAs(UnmanagedType.I4)]
[StructLayout(LayoutKind.Sequential)]
[1] http://en.wikipedia.org/wiki/Platform_Invocation_Services

287
[+1] [2008-09-19 19:20:30] ripper234

If 3rd-party extensions are allowed, then C5 [1] and Microsoft CCR [2] (see this blog post [3] for a quick introduction) are a must-know.

C5 complements .Net's somewhat lacking collections library (not Set???), and CCR makes concurrent programming easier (I hear it's due to be merged with Parallel Extensions).

[1] http://www.google.co.il/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fwww.itu.dk%2Fresearch%2Fc5%2F&ei=H_vTSPmZGZyw0gTK4t2VDQ&usg=AFQjCNEd1FXV-4rROqtPwZ_jDwmW1w5pFA&sig2=ILE99mEc76cQ6g-iRnPgbQ
[2] http://www.google.co.il/url?sa=t&source=web&ct=res&cd=2&url=http%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fbb648752.aspx&ei=N_vTSPzrComE0QSvwemcDQ&usg=AFQjCNFxZGL9m_QDWlvlkRNOpiLSG_q8bA&sig2=NGJmUpq-jE6kawcvaWWGYQ
[3] http://www.lnbogen.com/MicrosoftCCRCleanWayToWriteParallelCodeInNet.aspx

288
[+1] [2008-09-23 07:45:27] leppie

Some ?? weirdness :)

Delegate target =
  (target0 = target as CallTargetWithContext0) ??
  (target1 = target as CallTargetWithContext1) ??
  (target2 = target as CallTargetWithContext2) ??
  (target3 = target as CallTargetWithContext3) ??
  (target4 = target as CallTargetWithContext4) ??
  (target5 = target as CallTargetWithContext5) ??
  ((Delegate)(targetN = target as CallTargetWithContextN));

Interesting to note the last cast that is needed for some reason. Bug or by design?


289
[+1] [2008-11-18 10:54:30] Enes

Here is a TIP [1] of how you can use #Region directive to document your code.

[1] https://stackoverflow.com/questions/169276/is-the-region-directive-really-useful-in-net#287438

290
[+1] [2009-03-31 04:18:58] sudocracy

Not hidden, but pretty neat. I find this a more succinct substitute for a simple if-then-else that just assigns a value based on a condition.

string result = 
              i < 2 ?               //question
              "less than 2" :       //answer
              i < 5 ?               //question
             "less than 5":         //answer   
              i < 10 ?              //question
              "less than 10":       //answer
              "something else";     //default answer 

(6) However, the comparisons are either in the wrong order (i.e. compare 2, then 5, then 10) or they are the comparison is the wrong direction (i.e. test for greater than instead of less than). When i = 1, it will set result to "less than 10". - Mark
(8) That happens when you use such an illegible construct. - Juanma
if statements are far more readable than that. This version simply gives you street cred :) - Razor
Just use an if statement man! - Grokys
max street cred: ` var s = new SortedList<int, string> { { 2, "less than 2" }, { 5, "less than 5" }, { 10, "less than 10" } } .Where(kv => i < kv.Key) .Select(kv => kv.Value) .FirstOrDefault()?? "something else"; ` - sehe
291
[+1] [2009-06-03 14:53:50] Showtime

If you want to prevent the garbage collector from running the finalizer of an object, just use GC.SuppressFinalize(object);. In a similar vein, GC.KeepAlive(object); will prevent the garbage collector from collecting that object by referencing it. Not very commonly used, at least in my experience, but nice to know just in case.


292
[+1] [2009-07-17 14:29:23] RandomNickName42

Exception Filters [1]. So "hidden" you can't even use them (at least from C#) without a post-compilation patch ;)

[1] http://code.msdn.microsoft.com/ExceptionFilterInjct

Sorry, but that is not a language feature. It is an software instrumentation method (akin to profiling, tracing, AOP weavers, verifiers etc). It is a side effect of having a structured VM instruction set (like Perl, Python, Java and CLR, to name a few) - sehe
293
[+1] [2009-08-05 17:20:36] Ray

When you need to (a)synchronously communicate between objects about occurance of an event there is special purpose interface called ISynchronizeInvoke.

Quoting MSDN article ( link [1]):

Objects that implement this interface can receive notification that an event has occurred, and they can respond to queries about the event. In this way, clients can ensure that one request has been processed before they submit a subsequent request that depends on completion of the first.

Here is a generic wrapper:

protected void OnEvent<T>(EventHandler<T> eventHandler, T args) where T : EventArgs
{
    if (eventHandler == null) return;

    foreach (EventHandler<T> singleEvent in eventHandler.GetInvocationList())
    {
        if (singleEvent.Target != null && singleEvent.Target is ISynchronizeInvoke)
        {
            var target = (ISynchronizeInvoke)singleEvent.Target;

            if (target.InvokeRequired) {
                target.BeginInvoke(singleEvent, new object[] { this, args });
                continue;
            }
        }
        singleEvent(this, args);
    }
}

and here is an example usage:

public event EventHandler<ProgressEventArgs> ProgressChanged;

private void OnProgressChanged(int processed, int total)
{
    OnEvent(ProgressChanged, new ProgressEventArgs(processed, total));
}
[1] http://msdn.microsoft.com/en-us/library/system.componentmodel.isynchronizeinvoke.aspx

294
[+1] [2010-05-16 09:55:53] Razor

Separate static fields depending on the generic type of the surrounding class.

    public class StaticConstrucEx2Outer<T> {

 // Will hold a different value depending on the specicified generic type
 public T SomeProperty { get; set; }

 static StaticConstrucEx2Outer() {
  Console.WriteLine("StaticConstrucEx2Outer " + typeof(T).Name);
 }

 public class StaticConstrucEx2Inner<U, V> {

  static StaticConstrucEx2Inner() {

   Console.WriteLine("Outer <{0}> : Inner <{1}><{2}>",
    typeof(T).Name,
    typeof(U).Name,
    typeof(V).Name);
  }

  public static void FooBar() {}
 }

 public class SCInner {

  static SCInner() {
   Console.WriteLine("SCInner init <{0}>", typeof(T).Name);
  }

  public static void FooBar() {}
 }
}


StaticConstrucEx2Outer<int>.StaticConstrucEx2Inner<string, DateTime>.FooBar();
StaticConstrucEx2Outer<int>.SCInner.FooBar();

StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, DateTime>.FooBar();
StaticConstrucEx2Outer<string>.SCInner.FooBar();

StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, Int16>.FooBar();
StaticConstrucEx2Outer<string>.SCInner.FooBar();

StaticConstrucEx2Outer<string>.StaticConstrucEx2Inner<string, UInt32>.FooBar();

StaticConstrucEx2Outer<long>.StaticConstrucEx2Inner<string, UInt32>.FooBar();

Will produce the following output

Outer <Int32> : Inner <String><DateTime>
SCInner init <Int32>

Outer <String> : Inner <String><DateTime>
SCInner init <String>

Outer <String> : Inner <String><Int16>

Outer <String> : Inner <String><UInt32>

Outer <Int64> : Inner <String><UInt32>

I can only see static constuctors. None of the classes are defined as static... - MPritchard
@sehe: My comment was related to the original opening line - 'You can have instances of static classes'. This was edited 40 mins after my comment, presumably in response - MPritchard
@MPritch: mmm. ok I'll delete my comment then as it is not helpful, perhaps you could do the same and no-one will even know we were here :) - sehe
295
[0] [2010-02-19 03:54:47] rerun

I don't know if this is a hidden feature (""). Any string function.


"".func() also works but what good use can we possibly put it to? - Serhat Ozgel
(1) Just a quick shortcut for the non static functions - rerun
I saw some code recently that did pretty much the same thing. ((SomeType)null).SomeMethod(); -- I did a double-take, thought for a few seconds, and then grinned. :-) - Pretzel
(2) @pretezel wait, what? wouldn't that exception unless SomeMethod() was an extension method? - Fowl
296