Skip to content

Paulo Morgado
Syndicate content Paulo Morgado [EN]
.NET and Software Architecture and Engeneering
Updated: 22 hours 26 min ago

Hydrating Objects With Expression Trees - Part III

Wed, 08/18/2010 - 03:27
LINQ With C# (Portuguese)

To finalize this series on object hydration, I’ll show some performance comparisons between the different methods of hydrating objects.

For the purpose of this exercise, I’ll use this class:

class SomeType
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTimeOffset CreationTime { get; set; }
    public Guid UniqueId { get; set; }
}

and this set of data:

var data = (
    from i in Enumerable.Range(1, ObjectCount)
    select new object[] { i, i.ToString(), DateTimeOffset.Now, Guid.NewGuid() }
).ToArray();

The data bellow shows the time (in seconds) for different runs for different values of ObjectCount (in the same machine with approximately the same load) as well as it’s availability for different version of the .NET Framework and the C# programming language:

10000 100000 1000000 Valid for Setup Hydrate Total Setup Hydrate Total Setup Hydrate Total Framework version C# Version Activation and Reflection setter 0.060 0.101 0.161 0.055 0.736 0.791 0.054 6.822 6.876 1.0, 1.1, 2.0, 3.5, 4.0 1.0, 2.0, 3.0, 4.0 Activation and Expression Tree setter 0.300 0.003 0.303 0.313 0.049 0.359 0.293 0.578 0.871 4.0 none Member Initializer 0.035 0.001 0.036 0.039 0.027 0.066 0.041 0.518 0.559 3.5, 4.0 3.0, 4.0

These values will vary with the number of the objects being hydrated and the number of its properties, but the method using the Member Initializer will be the most performant.

Code samples for this series of posts (and the one about object dumping with expression trees) can be found on my MSDN Code Gallery: Dump And Hydrate Objects With Expression Trees


Categories: Blogs

Hydrating Objects With Expression Trees - Part II

Tue, 08/17/2010 - 00:19

LINQ With C# (Portuguese)

In my previous post I showed how to hydrate objects by creating instances and setting properties in those instances.

But, if the intent is to hydrate the objects from data, why not having an expression that does just that? That’s what the member initialization expression is for.

To create such an expression we need the constructor expression and the property binding expressions:

var properties = objectType.GetProperties();
var bindings = new MemberBinding[properties.Length];
var valuesArrayExpression = Expression.Parameter(typeof(object[]), "v");

for (int p = 0; p < properties.Length; p++)
{
    var property = properties[p];

    bindings[p] = Expression.Bind(
        property,
        Expression.Convert(
            Expression.ArrayAccess(
                valuesArrayExpression,
                Expression.Constant(p, typeof(int))
            ),
            property.PropertyType
        )
    );
}

var memberInitExpression = Expression.MemberInit(
    Expression.New(objectType),
    bindings
);

var objectHidrationExpression = Expression.Lambda<Func<object[], object>>(memberInitExpression, valuesArrayExpression);

var compiledObjectHidrationExpression = objectHidrationExpression.Compile();

This might seem more complex than the previous solution, but using it is a lot more simple:

for (int o = 0; o < objects.Length; o++)
{
    newObjects[o] = compiledObjectHidrationBLOCKED EXPRESSION;
}


Categories: Blogs

Hydrating Objects With Expression Trees - Part I

Mon, 08/16/2010 - 02:55

LINQ With C# (Portuguese)

After my post about dumping objects using expression trees, I’ve been asked if the same could be done for hydrating objects.

Sure it can, but it might not be that easy.

What we are looking for is a way to set properties on objects of an unknown type. For that, we need to generate methods to set each property of the objects.

Such methods would look like this expression:

Expression<Action<object, object>> expression = (o, v) => ((SomeType)o).Property1 = (PropertyType)v;

Unfortunately, we cannot use the .NET Reflector trick because, if you try to compile this, you’ll get this error:

error CS0832: An expression tree may not contain an assignment operator

Fortunately, that corresponds to a valid .NET expression tree. We just have to build it by hand.

So, for a given type, the set of property setters would be built this way:

var compiledExpressions = (from property in objectType.GetProperties()
                           let objectParameterExpression = Expression.Parameter(typeof(object), "o")
                           let convertedObjectParameteExpressionr = Expression.ConvertChecked(objectParameter, objectType)
                           let valueParameter = Expression.Parameter(propertyType, "v")
                           let convertedValueParameter = Expression.ConvertChecked(valueParameter, property.PropertyType)
                           let propertyExpression = Expression.Property(convertedObjectParameter, property)
                           select
                                Expression.Lambda<Action<object, object>>(
                                    Expression.Assign(
                                        propertyExpression,
                                        convertedValueParameter
                                    ),
                                    objectParameter,
                                    valueParameter
                                ).Compile()).ToArray();

And hydrating objects would be like this:

for (int o = 0; o < objects.Length; o++)
{
    var objectProperties = objects[o];

    var newObject = newObjects[o] = Activator.CreateInstance(objectType);

    for (int p = 0; p < compiledExpressions.Length; p++)
    {
        compiledExpressions[p](newObject, objectProperties[p]);
    }
}


Categories: Blogs

Mastering Expression Trees With .NET Reflector

Fri, 08/06/2010 - 02:40

Following my last post, I received lots of enquiries about how got to master the creation of expression trees.

The answer is: .NET Reflector

On that post I needed to to generate an expression tree for this expression:

Expression<Func<object, object>> expression = o => ((object)((SomeType)o).Property1);

I just compiled that code in Visual Studio 2010, loaded the assembly in .NET Reflector, and disassembled it to C# without optimizations (View –> Options –> Disassembler –> Optimization: None).

The disassembled code looked like this:

Expression<Func<object, object>> expression;
ParameterExpression CS$0$0000;
ParameterExpression[] CS$0$0001;
expression = Expression.Lambda<Func<object, object>>(Expression.Convert(Expression.Property(Expression.Convert(CS$0$0000 = Expression.Parameter(typeof(object), "o"), typeof(SomeType)), (MethodInfo) methodof(SomeType.get_Property1)), typeof(object)), new ParameterExpression[] { CS$0$0000 });

After giving valid C# names to the variables and tidy up the code a bit, I came up with this:

ParameterExpression parameter = Expression.Parameter(typeof(object), "o");
Expression<Func<object, object>> expression =
    Expression.Lambda<Func<object, object>>(
        Expression.Convert(
            Expression.Property(
                Expression.Convert(
                    parameter,
                    typeof(SomeType)
                ),
                "Property1"
            ),
            typeof(object)
        ),
        parameter
    );

Easy! Isn’t it?


Categories: Blogs

Dumping Objects Using Expression Trees

Tue, 08/03/2010 - 02:36

LINQ With C# (Portuguese)

No. I’m not proposing to get rid of objects.

A colleague of mine was asked if I knew a way to dump a list of objects of unknown type into a DataTable with better performance than the way he was using.

The objects being dumped usually have over a dozen of properties, but, for the sake of this post, let’s assume they look like this:

class SomeClass
{
    public int Property1 { get; set; }
    public long Property2 { get; set; }
    public string Property3 { get; set; }
    public object Property4 { get; set; }
    public DateTimeOffset Property5 { get; set; }
}

The code he was using was something like this:

var properties = objectType.GetProperties();

foreach (object obj in objects)
{
    foreach (var property in properties)
    {
        property.GetValue(obj, null);
    }
}

For a list of one million objects, this is takes a little over 6000 milliseconds on my machine.

I immediately thought: Expression Trees!

If the type of the objects was know at compile time, it would be something like this:

Expression<Func<SomeClass, int>> expression = o => o.Property1;
var compiled = expression.Compile();
var propertyValue = compiled.Invoke(obj);

But, at compile time, the type of the object and, consequently, the type of its properties, is unknown. So, we’ll need, for each property, an expression tree like this:

Expression<Func<object, object>> expression = o => ((SomeClass)o).Property1;

The previous expression gets the value of a property of the conversion of the parameter of type object to the type of the object. The result must also be converted to type object because the type of the result must match the type of the return value of the expression.

For the same type of objects, the collection of property accessors would be built this way:

var compiledExpressions = (from property in properties
                           let objectParameter = Expression.Parameter(typeof(object), "o")
                           select
                             Expression.Lambda<Func<object, object>>(
                                 Expression.Convert(
                                     Expression.Property(
                                         Expression.Convert(
                                             objectParameter,
                                             objectType
                                         ),
                                         property
                                     ),
                                     typeof(object)
                                 ),
                                 objectParameter
                             ).Compile()).ToArray();

Looks bit overcomplicated, but reading all properties of all objects for the same object set with this code:

foreach (object obj in objects)
{
    foreach (var compiledExpression in compiledExpressions)
    {
        compiledExpression (obj);
    }
}

takes a little over 150 milliseconds on my machine.

That’s right. 2.5% of the previous time.


Categories: Blogs

C#: More On Array Variance

Mon, 08/02/2010 - 02:06

In a previous post, I went through how arrays have are covariant in relation to the type of its elements, but not safely covariant.

In the following example, the second assignment is invalid at run time because, although the type of the objectArray variable is array of object, the real type of the array is array of string and an object cannot be assigned to a string.

object[] objectArray = new string[] { "string 1", "string 2" };
objectArray[0] = "string 3";
objectArray[1] = new object();

On the other hand, because arrays are not contravariant in relation to the type of its elements, in the following code, the second line will fail at run time because string[] ≤ object[].

object[] objectArray = new object[] { "string 1", "string 2" };
string[] stringArray = (string[])objectArray;

The fact that all elements in the object array are strings doesn’t make it convertible to an array of string. To convert this object array of strings into a string array, you’ll need to create a new string array and copy each converted element.

The conversion can be as easily as this:

string[] stringArray = objectArray.Cast<string>().ToArray();

The above code is just shorthand to traversing the whole array while converting its elements to string and creating an string array with all elements.

Arrays are a good storage structure because they are the only structure provided by the runtime to store groups of items of the same type. However, because of limitations like the above, its use in APIs should be very carefully considered.

If all you need is to traverse all elements of some collection, you should use an IEnumerable<T> (IEnumerable<out T> in .NET 4.0). This way, the cost of using Enumerable.Cast<T>() is minimal.


Categories: Blogs

O Estranho Caso Do Computador Que Acordava Sozinho Misteriosamente

Wed, 07/21/2010 - 00:56

Normalmente, quando eu vou dormir, também ponho o meu computador a dormir.

Mas, desde há alguns meses, o computador acordava sozinho e eu não conseguia percber porquê.

Com a ajuda do Pete consegui perceber porquê:

C:\>PowerCfg -LASTWAKE
Wake History Count - 1
Wake History [0]
  Wake Source Count - 1
  Wake Source [0]
    Type: Wake Timer
    Owner: [PROCESS] \Device\HarddiskVolume2\Windows\System32\services.exe
    Owner Supplied Reason: Windows will execute '\Microsoft\Windows\Media Center\mcupdate_scheduled' scheduled task that requested waking the computer.

Usando PowerCfg –LASTWAKE é possível saber o que acordou o computador da última vez que este acordou.

Afinal era apenas uma tarefa agendada do Media Center que acordava o meu computador.


Categories: Blogs

The Strange Case Of The Mysterious Self Awaking Computer

Wed, 07/21/2010 - 00:56

Usually, when I go to sleep, I also put my desktop computer to sleep.

But, for the last couple of months, the computer would always wake up by itself and I couldn’t figure out why.

With the help of Pete I was able to find out:

C:\>PowerCfg -LASTWAKE
Wake History Count - 1
Wake History [0]
  Wake Source Count - 1
  Wake Source [0]
    Type: Wake Timer
    Owner: [PROCESS] \Device\HarddiskVolume2\Windows\System32\services.exe
    Owner Supplied Reason: Windows will execute '\Microsoft\Windows\Media Center\mcupdate_scheduled' scheduled task that requested waking the computer.

Using PowerCfg –LASTWAKE it is possible to know what woke up the computer the last time it woke up.

It turns out that it was a Media Center scheduled task that was waking up my computer.


Categories: Blogs

How To Add And Remove SQL Server 2008 / 2008R2 Instances

Fri, 07/02/2010 - 02:18

After installing Visual Studio 2010 I, inadvertently ended up with SQL Server 2008 Express having already installed SQL Server 2008 Developer. Only when I was going to upgrade to SQL Server 2008R2 I found out I had two instances installed.

I looked everywhere for a place to remove the SQLEXPRESS instance but couldn’t find it.

Only when I decided to uninstall the entire SQL Server suite and start over I found how to do it.

On Windows 7, go to Programs and Features and choose Microsoft SQL Server 2008 R2 (64-bit) (or whatever your version of SQL Server you want to add or remove and instance from).

Choose Remove (or Add, if you want to add a new instance).

Follow the steps and choose which instance you want to remove.

Select the features of that instance you want to remove (select all to remove the instance).
Note: Don’t remove shared features if you don’t want to remove any other instances.

It’s probably something I should have known, but I didn’t and it wasn’t easy to find.


Categories: Blogs

Fixing Windows Virtual PC Missing “Create Virtual Machine” Folder Option

Sun, 06/20/2010 - 19:54

Some of my Windows 7 systems, after installing Windows Virtual PC, were missing the Create virtual machine option.

Bob Comer directed me to this post from the Virtual PC Guy's Blog but, before trying the recipes in the post (which involved logging out or restarting the system), I simply tried the Reset Folders option in the View tab of the Folder Options. And it immediately solved the problem.

So, if you are having this same problem, you might want to try this simple solution first.

In the end, just in case, I also added start menu shortcuts to:

  • Windows Virtual PC Wizard

    %SystemRoot%\System32\VPCWizard.exe

  • Windows Virtual PC Settings

    %SystemRoot%\System32\VPCSettings.exe


Categories: Blogs

Is Your ASP.NET Development Server Not Working?

Tue, 06/15/2010 - 02:31

Since Visual Studio 2005, Visual Studio comes with a development web server: the ASP.NET Development Server.

I’ve been using this web server for simple test projects since than with Visual Studio 2005 and Visual Studio 2008 in Windows XP Professional on my work laptop and Windows XP Professional, Windows Vista 64bit Ultimate and Windows 7 64bit Ultimate at my home desktop without any problems (apart the known custom identity problem, that is).

When I received my new work laptop, I installed Windows Vista 64bit Enterprise and Visual Studio 2008 and, for my surprise, the ASP.NET Development Server wasn’t working.

I started looking for differences between the laptop environment and the desktop environment and the most notorious differences were:

System

Laptop

Desktop

SKU

Windows Vista 64bit Enterprise

Windows Vista 64bit Ultimate

Joined to a Domain

Yes

No

Anti-Virus

McAffe

ESET

After asserting that no domain policies were being applied to my laptop and domain user and nothing was being logged by the ant-virus, my suspicions turned to the fact that the laptop was running an Enterprise SKU and the desktop was running an Ultimate SKU. After having problems with other applications I was sure that problem was the Enterprise SKU, but never found a solution to the problem. Because I wasn’t doing any web development at the time, I left it alone.

After upgrading to Windows 7, the problem persisted but, because I wasn’t doing any web development at the time, once again, I left it alone.

Now that I installed Visual Studio 2010 I had to solve this. After searching around forums and blogs that either didn’t offer an answer or offered very complicated workarounds that, sometimes, involved messing with the registry, I came to the conclusion that the solution is, in fact, very simple.

When Windows Vista is installed, hosts file, according to this contains this definition:

127.0.0.1       localhost
::1             localhost

This was not what I had on my laptop hosts file. What I had was this:

#127.0.0.1       localhost
#::1             localhost

I might have changed it myself, but from the amount of people that I found complaining about this problem on Windows Vista, this was probably the way it was.

The installation of Windows 7 leaves the hosts file like this:

#127.0.0.1       localhost
#::1             localhost

And although the ASP.NET Development Server works fine on Windows 7 64bit Ultimate, on Windows 7 64bit Enterprise it needs to be change to this:

127.0.0.1       localhost
::1             localhost

And I suspect it’s the same with Windows Vista 64bit Enterprise.


Categories: Blogs

Detecting User Regional Settings In The Web Browser

Mon, 05/10/2010 - 03:07

Recently, a friend of mine asked me something like: “How do I get the user’s regional settings for a request to a web server?”

As far as I know, web browser only send an Accept-Language HTTP header and nothing more. You can take this and use the default regional settings for that language but, if your user is anything like me, you’ll be wrong.

So, what’s the problem of getting it wrong?

If you are just generating HTML and keep it consistent, nothing’s wrong. But what if your user wants to copy some numeric and/or date values to, say, Excel? Or if you want to export some data as a CSV file?

A solution

Going through the JScript Language Reference, I found that both Number and Date have locale related toString methods and I started playing with them.

Numeric format settings

To the numeric format settings, first we need a number that will behave in a predictable manner in any culture (“any culture” means “any culture I know”) and for all possible settings and convert it to a string using the toLocaleString method:

var number = 111111111.111111111;
var numberString = number.toLocaleString();

(With my regional settings, numberString becomes 111 111 111.11)

To get the decimal separator, all it takes is getting the first non 1 from the end:

var decimalSeparator;
var decimalDigits;
for (var i = numberString.length - 1; i >= 0; i--) {
    var char = numberString.charAt(i);
    if (char != "1") {
        decimalSeparator = char;
        decimalDigits = numberString.length - i - 1;
        break;
    }
}

And if you count how many 1s were skipped, we get the number of decimal digits.

In a similar way, the first non 1 will be the digit grouping separator:

var groupSeparator;
for (var i = 0; i < numberString.length; i++) {
    var char = numberString.charAt(i);
    if (char != "1") {
        groupSeparator = char;
        break;
    }
}

Now that we have the digit grouping separator, we can get the digit groups (these groups might not all have the same size):

var digitGrouping = numberString.substring(0, numberString.length - decimalDigits - 1).split(groupSeparator);
for (g in digitGrouping) {
    digitGrouping[g] = digitGrouping[g].length;
}
Date and time settings

Date and time values are more difficult to parse and you might not need all information. So, I’ll just get the value and let the parsing to you:

var dateTime = new Date(9999, 11, 31, 23, 30, 45);
dateTimeString = dateTime.toLocaleString();
List settings

The last setting is the list separator (very useful for those CSV files):

var list = ["a", "b"];
listSeparator = list.toLocaleString().substring(1, 2);
Test page

Here is a test page the get all these settings:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Test Page</title>
    <style type="text/css">
        label  { width: 8em; text-align: right; padding-right: 0.5em; white-space: nowrap; }
        span { border: 1px solid; white-space: nowrap; }
    </style>
    <script type="text/javascript">
        function init() {
            document.all.userLanguage.innerText = window.navigator.userLanguage;
            document.all.systemLanguage.innerText = window.navigator.systemLanguage;

            // Decimal separator and decimal digits
            var number = 111111111.111111111;
            var numberString = (111111111.111111111).toLocaleString();

            var decimalSeparator;
            var decimalDigits;
            for (var i = numberString.length - 1; i >= 0; i--) {
                var char = numberString.charAt(i);
                if (char != "1") {
                    decimalSeparator = char;
                    decimalDigits = numberString.length - i - 1;
                    break;
                }
            }
            document.all.decimalSeparator.innerText = decimalSeparator;
            document.all.decimalDigits.innerText = decimalDigits;

            // Digit grouping separator and digit goups
            var groupSeparator;
            for (var i = 0; i < numberString.length; i++) {
                var char = numberString.charAt(i);
                if (char != "1") {
                    groupSeparator = char;
                    break;
                }
            }
            document.all.groupSeparator.innerText = groupSeparator;

            var digitGrouping = numberString.substring(0, numberString.length - decimalDigits - 1).split(groupSeparator);
            for (g in digitGrouping) {
                digitGrouping[g] = digitGrouping[g].length;
            }
            document.all.digitGrouping.innerText = digitGrouping.toString();

            // Date format
            var dateTime = new Date(9999, 11, 31, 23, 30, 45);
            var dateTimeString = dateTime.toLocaleString();
            document.all.dateTimeFormat.innerText = dateTimeString;

            // List separator
            var list = ["a", "b"];
            var listSeparator = list.toLocaleString().substring(1, 2);
            document.all.listSeparator.innerText = listSeparator;
        }
    </script>
</head>
<body onload="init()">
    <p><label for="userLanguage">User language:</label><span id="userLanguage"></span></p>
    <p><label for="systemLanguage">System language:</label><span id="systemLanguage"></span></p>
    <p><label for="decimalSeparator">Decimal separator:</label><span id="decimalSeparator"></span></p>
    <p><label for="decimalDigits">Decimal digits:</label><span id="decimalDigits"></span></p>
    <p><label for="groupSeparator">Digit separator:</label><span id="groupSeparator"></span></p>
    <p><label for="digitGrouping">Digit grouping:</label><span id="digitGrouping"></span></p>
    <p><label for="dateTimeFormat">Date/Time format:</label><span id="dateTimeFormat"></span></p>
    <p><label for="listSeparator">List separator:</label><span id="listSeparator"></span></p>
</body>
</html>


Categories: Blogs