In C#, you can use the object/collection ini­tial­iza­tion syn­tax like this:

image

The F# equiv­a­lent of object ini­tial­iza­tion is done like this:

image

As for col­lec­tion ini­tial­iza­tion, you have a far more diverse range of tools avail­able to you, for example:

image

You can also cre­ate slices of an exist­ing array:

image

You can even add your own multi-dimensional index­ers to sup­port sim­i­lar behav­iours in your type too!

Update 2012/01/11:

As Robert Pick­er­ing men­tioned in the com­ments, slic­ing is not lim­ited to arrays, it works with other col­lec­tion types too (as long as a Get­Slice exten­sion method is defined on the type, for more infor­ma­tion, see here). For instance, you can use slic­ing on a string like this:

image

With 2D arrays, you can also use a multi-dimensional slicer too:

image

Share

If you’re read­ing this post, you prob­a­bly know about F#’s Units of Mea­sure already, it’s very use­ful when work­ing with real-world units and adds extra safety to code that needs to work with and con­vert from one unit to another.

Here’s a quick snip­pet that shows you how to define and use units-of-measure:

image

This code out­puts the fol­low­ing, note the units asso­ci­ated with the float values:

image

As you can see, units of mea­sure can also be com­pounded by mul­ti­pli­ca­tion or division!

If you have a func­tion that requires a int<m>, you won’t be able to call the func­tion with a nor­mal int, hence pro­vid­ing you with extra pro­tec­tion to ensure the cor­rect­ness of your appli­ca­tion because the unit of a numeric value is now a for­mal con­tract between a func­tion and its caller:

image

Hav­ing said that, there are cases where you want to be able to con­vert between an int and an int<m>. For instance, to pro­vide bet­ter inter­op­er­abil­ity with other .Net lan­guages, as units-of-measure only exists in F# there’s no way to cre­ate a numeric value with units-of-measure in C# (that I’m aware of anyway).

To con­vert from int<m> to int (or any other numeric type) is easy, just do a straight cast:

image

Going the other way is slightly more tricky, you can’t use int<m> to cast an int to an int<m>, but you can either mul­ti­ply the value with 1<m> or use the Int32WithMeasure method on the Lan­guagePrim­i­tives core module:

image

Share

In C#, you define an empty class, struct, or inter­face like this:

image

So how do you define an empty type in F#?

Well, when­ever you define a new class in F#, the com­piler infers the class and end tokens at the begin­ning and end of the class’s def­i­n­i­tion, as you can see from below:

image

So the eas­i­est way to define an empty type is to spec­ify the class and end tokens explicitly:

image

Run­ning these few lines of code into the F# inter­ac­tive out­puts the following:

image

For class types, you also have other alter­na­tive tech­niques, such as:

image

Share

There’re a num­ber of built-in lit­eral types in F#, and one of the cool things you can do is to get the byte or byte array rep­re­sen­ta­tion of a char or string using the ‘B’ suf­fix, the result is the same as Encoding.ASCII.GetBytes:

image

Pretty cool, eh?

Share

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