Saturday, June 25, 2011

Labmda Expressions

So, Lambda Expressions were one of the major syntax additions in C# 3.0. At first glance, you might think "Oh these seem kind of silly. Why would I ever want to use these?"

But what you don't know is that that kind of thinking truly hurts their feelings and is just wrong of you since they are in fact awesome. I'm not sure how you live with yourself.


What kind of monster are you???

But anyway, yeah. Lambda Expressions are a nice an easy way to write an inline function.

Their format is:
arguments, arrow thingy, method.

There's a few different ways to write them.
Here are some examples.
(x, y) => { return x * y; }
() => MessageBox.Show("Tina, come get some ham!");
x => x * x;



No seriously, come get some ham.

So, let's start with the arguments.
* You can have any number of arguments -- even no arguments if you're that kind of guy.
* If there are no arguments, use open and close parentheses. ()
* If there are multiple arguments, separate them by commas and surround them with parentheses. (x, y, z)
* If there's one argument, you can you parentheses if you so desire, but you don't have to.

The arrow thingy:
* Looks like this: =>
* That's about it for the arrow thingy.

The method:
* If there are multiple statements, surround with brackets. { asdf(); zxcv(); }
* If there's just one statement, brackets are optional. DoStuff()
* If it's one statement without brackets and that statement returns a value, that will be the resulting value of the expression. x => x * x
* If the method is in brackets, and you want the expression to return a value, you'll need to use the return statement. x => { return x * x;}


So, let's have some fun.
Action doSomething = () => { MessageBox.Show("asdf"); };
doSomething();

Func getSquare = x => x * x;
int y = getSquare(5);



Your mind has just been blown.

You can assign a Lambda Expression to a delegate that matches their signature.
You might not have seen Actions and Funcs before. These are just generic delegates that make it easy to assign a Lambda Expression. Func is for expressions that return a value. Action is for expressions that don't. Both of them can take in any number of parameters. Just separate the types by commas. For Func, the last type listed is the return type.

Action<string, string> writeFile = (fileName, fileContents) => File.WriteAllText(fileName, fileContents);


So...how is this useful?
Well, it's used a lot in LINQ which we'll get to later, but it has some other nice uses.
Ever want to log how long a method takes to run?
public static T LogTime<T>(Func<T> function, string description)
{
const string logFileName = "Timing.txt";

DateTime startTime = DateTime.Now;
T result = function();
DateTime endTime = DateTime.Now;

TimeSpan elapsedTime = endTime - startTime;
File.AppendAllText(logFileName, description + ": " + elapsedTime.TotalMilliseconds.ToString() + " ms");

return result;
}


How about doing a quick sort?
Here's a typical scenario.
You've got a whole bunch of muppets, but you really need to get them in order of how long their names are.

List<string> muppets = new List<string>{ "Ernie", "Kermit", "That weird shrimp guy", "Lew Zealand" };
muppets.Sort((muppetA, muppetB) => muppetA.Length - muppetB.Length);

Tuesday, May 31, 2011

Anonymous Classes

.NET 3.5 or Greater

One of the nice features of the "var" keyword is that it lets you create Anonymous Classes.
Anonymous classes allow for a quick and easy way to define an object that has named properties within a method.

Creating an Anonymous class is this simple:
var person = new { Name = "Bob", Age = 47 };


Properties can be accessed just like a regular class.
MessageBox.Show("Name: " + person.Name);


A few things to keep in mind.
  • All properties are read-only -- once you set them, you can't change them.
  • You can't declare them outside of a method.
  • You can't really do much with them outside of the method that they're created in. Sure, you could pass them to another method as an Object, but once you do, there's no way to cast them back and use their properties (short of using reflection).

So in the end, they're intended to intended to be temporary and localized.

They work great with LINQ though.

List<string> animalNames = new List<string> { "dog", "cat", "horse", "meerkat" };

var animals =
(
from animalName in animalNames
select new { Name = animalName, Lengh = animalName.Length, Hash = animalName.GetHashCode() }
).ToList();

animals.ForEach(animal =>
{
MessageBox.Show("Name: " + animal.Name + "; Hash: " + animal.Hash);
}
);


So, there's a few things going on in the code above.
If you're not familiar with LINQ, I'm planning on making a series of tutorials on it in the near future (or you can check out the links at the bottom of this post). But the code above goes through all the strings in animalNames and makes a list of Anonymous Classes containing the Name, Length, and Hash.

(You'll note that var is also being used to hold the List<> of Anonymous Classes. There are a few other things you can do with var besides creating Anonymous Classes and this is one of them.)

After that, it loops through all the Anonymous Classes that were created and displays them in a MessageBox to the user.

http://www.beansoftware.com/ASP.NET-Tutorials/Linq-Objects-Collections-Arrays.aspx
http://www.blackwasp.co.uk/LinqToObjectsTutorial.aspx
http://www.developerfusion.com/article/8250/linq-to-objects-for-the-net-developer/

Monday, May 30, 2011

Tuple

Tuple<T> is a new generic class in .NET 4.0 that makes it easy to combine multiple items of any type into one object. The concept is similar to any array. The advantage to a Tuple<T> is that the elements are individually typed and can be accessed without a subscript. This alleviates the danger of going outside of an array's bounds.


Tuple<int, string, char> x;


Tuples can have between 1 and 8 elements.
They can be instantiated either by using "new" or Tuple.Create()


Tuple<int, string, char> x = new Tuple<int, string, char>(1, "asdf", 'c');
Tuple<bool, float, decimal> y = Tuple.Create(true, 1.0f, 2.3m);


The items in a Tuple can be accessed using Tuple.Item1, Tuple.Item2, etc.


MessageBox.Show(y.Item2.ToString());


That's really all there is to it.
This is nice when you have multiple items that go together but don't really fit into a class.

Have fun.

Sunday, May 29, 2011

Being Lazy in .NET 4.0

Lazy<T> is a new class available in .NET 4.0 which simplifies Lazy Initialization.

http://en.wikipedia.org/wiki/Lazy_initialization

The basic idea is that a field isn't initialized until it's used.

In earlier versions of .NET this could be done by using a field and property in conjunction. If the field is null, the property initializes the field and returns it. If the field isn't null, the property just returns the field.
Bitmap _backBitmap = null;
Bitmap BackBitmap
{
get
{
if(_backBitmap == null)
{
_backBitmap = new Bitmap("background.jpg");
}

return _backBitmap;
}
}


Lazy<T> provides an easier way to accomplish this.

Lazy<Bitmap> BackBitmap
= new Lazy<Bitmap>( () => new Bitmap("background.jpg") );


Lazy<T> uses the type specified between the <> and its constructor takes in a Lambda Expression which returns the value to which the field is initialized.

If you're not familiar with Lambda Expressions, they're just a way of creating an inline function.

You can read more about them here:
http://blogs.msdn.com/b/ericwhite/archive/2006/10/03/lambda-expressions.aspx
http://www.codeproject.com/KB/cs/explore_lamda_exp.aspx
http://msdn.microsoft.com/en-us/library/bb397687.aspx

I'll probably do a post about them in the future too.