Wednesday, September 24, 2008

SequenceEqual is my favorite new hammer

A common programming task that many people face is comparing 2 enumerations to determine if they are equal. Ideally you would like to be able to write code like the following:

if(arrayA == arrayB)
{
//Do Stuff Here...
}

However as you know, arrayA will never equal arrayB in the code above since they are completely different objects. What you really want to know is if the values contained in arrayA are the same as the values contained in arrayB. Well, the SequenceEqual() method provides a mechanisim to do just that.

The SequenceEqual() method enumerates the two source sequences in parallel and compares corresponding elements by using the default equality comparer for TSource.

Here is a quick example showing 2 equal arrays...

string[] arrayA = new string[]{"a","b","c","d"};
string[] arrayB = new string[]{"a","b","c","d"};
string[] arrayC = new string[]{"w","x","y","z"};

bool A_Equals_B = arrayA.SequenceEqual(arrayB); //returns true;
bool A_Equals_C = arrayA.SequenceEqual(arrayC); //returns false;

Labels: , ,

Wednesday, August 6, 2008

Identifying the differences between CallContext Data Slots

Recently I was working on a server side caching strategy for permissions data. The key to the strategy was to place a user's permissions returned from a database call into the CallContext of WCF service. The code to do this looked something like this...

CallContext.SetData("permissionsKey", myPermissionsData);

All subsequent requests for permissions data would then be returned from the CallContext's cache permissions, thereby saving me from having to make redundant database calls for data that I already have.

myPermissionsData = (PermissionData)CallContext.LogicalGetData("permissionsKey")

Simple caching strategy...

During my testing I found that my cached data was not being returned. After further investigation I realized that I was setting the data using the CallContext's SetData method, but I was getting the data using the CallContext's LogicalGetData method. Come to find out, these are not the same. Seems there is a LogicalGetData method, LogicalSetData method, GetData method and SetData method on the CallContext object. So, it was a simple fix to use the LogicalSetData method in conjunction with the LogicalGetData method when implementing my caching strategy.

But why are there two methods that seemingly do the same thing? The documentation on MSDN doesn't really specify the differnce between the two.

Well... after doing some resarch and finding a post by Lucian Bargaoanu on the subject it seems that the difference has to do with AppDomains. Come to find out there is a LogicalCallContext and an IllogicalCallContext. LogicalCallContext will flow across appdomains. It will do this regardless of what type of object you have placed in context. The object doesn't have to implement ILogicalThreadAffinitive. When you call SetData with an ILogicalThreadAffinitive object, the data is set in the LogicalCallContext. When you call GetData it will first look in the LogicalCallContext and then in the IllogicalCallContext. You cannot have the same key in both CallContext(s).

In summary, objects stored using SetData will only flow across AppDomains if they implement ILogicalThreadAffinitive. Objects stored in LogicalSetData will flow across AppDomains even if they don't implement ILogicalThreadAffinitive. LogicalSetData handles seems to handle the ILogicalThreadAffinitive implementation for you.

Labels: , , , ,

Tuesday, July 29, 2008

Cool LINQ Tool

There is a cool LINQ tool called LINQPad available from O'Reilly.

It is pre-loaded with a bunch of great examples from C# 3.0 In a Nutshell by Joseph Albahari and
Ben Albahari

Check it out...

Labels: , , ,

Thursday, May 29, 2008

Neat coding tricks with LINQ

Igor Ostrovsky has compiled a list of 7 tricks to simplify common coding tasks using LINQ.

The LINQ approach to converting sequences or collections is very elegant.

Here are 101 other samples

Labels: , , ,