In C#, when you define an event in your class, e.g.:

image

the event han­dlers will be seri­al­ized along with other prop­er­ties, etc.

This is because under the hood, the com­piler trans­lates your event into the fol­low­ing, as can be seen through Jet­Brain’s dot­Peek decompiler:

image

Since the gen­er­ated Even­tHandler is not marked with the [Non­Se­ri­al­ized] attribute there’s no way for the seri­al­izer to know that it should be ignored dur­ing the seri­al­iza­tion process.

Solu­tion 1 : imple­ment event explicitly

One solu­tion to this is to imple­ment the event explic­itly, so you end up with some­thing along the line of:

image

Solu­tion 2 : use [field:NonSerialized]

A much bet­ter solu­tion would be to use the [Non­Se­ri­al­ized] attribute on the event, and more specif­i­cally, you want to apply it to the pri­vate Even­tHandler instance that the com­piler gen­er­ates for you. Apply­ing the [Non­Se­ri­al­ized] attribute on the event gen­er­ates a com­piler error telling you that it’s only valid on field declarations:

image

image

So instead, if you pre­fix the attribute with the ‘field’ key­word every­thing will work as you’d expect:

image

Clos­ing thoughts…

On a related note, you may have noticed that my event dec­la­ra­tion assigns an empty han­dler to the event, this is to remove the need for null check­ing before invok­ing an event (which as you can imag­ine requires even more work to make thread-safe). There are other tech­niques (see @BlkRabbitCoder’s post on rais­ing events safely and effi­ciently here for more details) to deal with this com­mon problem.

In the case of a class that has to be seri­al­ized, this tech­nique won’t work if the event han­dlers are not seri­al­ized as part of the object, because by the time it’s dese­ri­al­ized the event han­dler will be null.

So instead, cour­tesy of @BlkRabbitCoder, here’re two sim­ple exten­sion meth­ods that encap­su­lates the code nec­es­sary to safely (pre­vents Null­Ref­er­ence­Ex­cep­tion) invoke event han­dlers in a thread-safe manner:

image

Fur­ther reading

Here are some more blog posts that go in to more detail about some intri­ca­cies with events in .Net:

Jon Skeet – Del­e­gates and Events

Eric Lip­pert – Events and Races

Safely and Effi­ciently rais­ing Events

Share

Indexer

If your have a type that rep­re­sents a col­lec­tion of val­ues, adding a cus­tom indexer gives you a nat­ural way to index directly into the object using the .[ ] operator.

Take this sim­ple Cal­en­dar class for instance, which keeps a map (F# equiv­a­lent of a Dictionary<TKey, TValue>) of notes against Date­Time values:

image

By adding a cus­tom indexer here I’m now able to write code like this:

image

Also, as you may have noticed already, F# allows you to use non-integer para­me­ters in your indexer! In this case, I’m using a tuple of int * string * int. You can use this indexer from your C# code too:

image

One-Dimensional Slicer

That’s pretty cool, but we can go a step fur­ther by allow­ing you to use slicers on our types too. To allow users to get all the notes asso­ci­ated with a range of years, e.g. from 1999 to 2009, let’s add a slicer:

image

So now we can do this:

image

Two-Dimensional Slicer

Pretty awe­some, right? But what if we want to refine our search cri­te­ria even more and let you spec­ify a year range as well a range of months, e.g. get me all notes for April/May/June in the years 1999 to 2009. Thank­fully, F# lets you define a two-dimensional slicer too:

image

This two-dimensional slicer allows me to query the cal­en­dar with a year range as well as a month range:

image

As you can see, index­ers and slicers give the con­sumers of your code a much more intu­itive way to inter­act with the data encap­su­lated in your type. Keep in mind though, that F# does not allow you to add slicer with more than two dimen­sions, but I think two-dimensional slicers should be good enough for most day-to-day requirements.

Update 2011/11/08:

Swapped out my ver­bose optional argu­ment han­dling with default­Arg as Arseny Kapoulkine pointed out in the comments.

Share

I needed to find out which process is lis­ten­ing on a port the other day and a quick search on SO showed me the way and all you need is to run:

net­stat –aon | find /i “listening”

and you will get a list of the ports and the PID of the process lis­ten­ing on that port:

image 

Sweet!

Share

To get the default value of a type, you’ve prob­a­bly used the default key­word in .Net already:

   1: var defaultInt = default(int);        // 0

   2: var defaultObj = default(string);     // null

How­ever, the use of the default key­word requires a type name to be spec­i­fied at com­pile time, so you won’t be able to use it on a type which you dis­cover at run­time. Instead, you will need to do some­thing along the line of:

   1: public object GetDefaultValue(Type type)

   2: {

   3:     // Handle value types and reference types differently

   4:     if (type.IsValueType)

   5:     {

   6:         return Activator.CreateInstance(type);

   7:     }

   8:     else

   9:     {

  10:         return null;

  11:     }

  12: }

It’ll yield the same result as using the default keyword:

   1: var defaultInt = GetDefaultValue(typeof(int));        // 0

   2: var defaultObj = GetDefaultValue(typeof(string));     // null

Share

By default the GAC folder in Win­dows is located at %windir%\assembly, you can find all the reg­is­tered DLLs in that folder. Whilst you can open it in win­dows explorer and view it like any other folder, it is a some­what spe­cial and allows you to have dif­fer­ent ver­sions of the same DLL reg­is­tered in the GAC

Open up DOS prompt and nav­i­gate to the GAC folder, for instance:

image

and you can see that the GAC is actu­ally a folder inside the assem­bly folder, and drilling a lit­tle deeper reveals that each DLL has its own folder which con­tains all the reg­is­tered ver­sions, each as a folder that con­tains the actual DLL inside:

image 

image

image

.Net 4

For .Net 4, the GAC loca­tion is now %windir%\Microsoft.Net\assembly.

Global Assem­bly Cache Tool

You can use gacutil.exe from the com­mand line to view (e.g. gacu­til /l), add (e.g. gacu­til /i SomeAssembly.dll) or remove (e.g. gacu­til /u Some­Assem­bly) the con­tents of the GAC, this of course, sup­ports mul­ti­ple ver­sions of the same assem­bly too.

Share