Tag Archive | c#

C# Probably Getting New “Safe Navigation” Operator “?.”

It looks as if the Visual Studio dev team may be implementing a new operator in a future .NET release. This is due in large part to community demand, which is pretty cool because it shows that the VS team is listening to their customer base; a key part of a successful product.

This new operator is likely going to take the syntax of ?. and is known as the Safe Navigation Operator.

Its purpose is rather simple, and it eliminates a load of boiler-plate code by making the compiler do it for you.

Say you have these classes:

public class A
{
    public B B { get; set; }
}

public class B
{
    public C C { get; set; }
}

public class C
{
    public int D { get; set; }
}

It’s plain to see above that it’s possible that an instance of A may have a null B property, or even that an instance of B may have a null C property. If you want to get D from A safely (so as to avoid null reference exceptions), your code often ends up looking something like this:

int? result = A.B == null ? (int?)null : 
    (A.B.C == null ? (int?)null : A.B.C.D);

What an incredibly annoying pain to write out, and even to read. You could maybe make it clearer, at the cost of more verbosity and lines of code:

int? result = null;
if (A.B != null)
{
    if (A.B.C != null)
    {
        result = A.B.C.D;
    }
}

This is still a bit convoluted and boiler-plate for my liking. Really, all we want to do in English is get the integer value of D if it exists on A. It shouldn’t be so challenging!

Enter the new Safe Navigation Operator and how it might function:

int? result = A?.B?.C.D;

Note the ?. that is placed at the point where the A instance references B and B instance references C. This is much more readable, and intuitive to look at. To me, it says “if A’s B is not null and B’s C is not null, return D, else return null” which is pretty streamlined. Upon simple inspection, it also clearly says that A.B is nullable and B.C is nullable, which are great side effects of the shortened syntax.

Note that the final product, if included in C#, may behave differently than I’ve demonstrated and hypothesized here. The code in this post is mostly made on assumptions of compiler rules for this operator, and could in the future prove to be wrong. However, even still, this operator will be a great addition to C# and .NET if it makes the cut!

Trigger IValidatableObject.Validate When ModelState.IsValid is false

I recently came across an ASP.NET MVC issue at work where the validation for my Model was not firing correctly. The Model implemented the IValidatableObject interface and thus the Validate method which did some specific logic to ensure the state of the Model (the ModelState). This Model also had some DataAnnotation attributes on it to validate basic input.

Long story short, the issue I encountered was that when ModelState.IsValid == false due to failure of the DataAnnotation validation, the IValidatableObject.Validate method is not fired, even though I needed it to be. This problem arose due to a rare situation in which ModeState.IsValid was initially false but was later set to true in the Controller’s Action Method by some logic that removed errors from the ModelState.

I did some research and learned that the DefaultModelBinder of ASP.NET MVC short-circuits it’s logic: if the ModelState is not valid (AKA is false), the IValidatableObject logic that runs the Validate method is never fired.

To thwart this, I created a custom Model Binder, a custom Model Binder Provider (to serve my custom Model Binder), and then registered the Model Binder Provider in the Application_Start method of Global.asax.cs. Here’s the code for a custom Model Binder that always fires the IValidatableObject.Validate method, even if ModelState.IsValid == false:

ForceValidationModelBinder:

/// <summary>
/// A custom model binder to force an IValidatableObject to execute the Validate method, even when the ModelState is not valid.
/// </summary>
public class ForceValidationModelBinder : DefaultModelBinder
{
    protected override void OnModelUpdated( ControllerContext controllerContext, ModelBindingContext bindingContext )
    {
        base.OnModelUpdated( controllerContext, bindingContext );

        ForceModelValidation( bindingContext );
    }

    private static void ForceModelValidation( ModelBindingContext bindingContext )
    {
        // Only run this code for an IValidatableObject model
        IValidatableObject model = bindingContext.Model as IValidatableObject;
        if( model == null )
        {
            // Nothing to do
            return;
        }

        // Get the model state
        ModelStateDictionary modelState = bindingContext.ModelState;

        // Get the errors
        IEnumerable<ValidationResult> errors = model.Validate( new ValidationContext( model, null, null ) );

        // Define the keys and values of the model state
        List<string> modelStateKeys = modelState.Keys.ToList();
        List<ModelState> modelStateValues = modelState.Values.ToList();

        foreach( ValidationResult error in errors )
        {
            // Account for errors that are not specific to a member name
            List<string> errorMemberNames = error.MemberNames.ToList();
            if( errorMemberNames.Count == 0 )
            {
                // Add empty string for errors that are not specific to a member name
                errorMemberNames.Add( string.Empty );
            }

            foreach( string memberName in errorMemberNames )
            {
                // Only add errors that haven't already been added.
                // (This can happen if the model's Validate(...) method is called more than once, which will happen when there are no property-level validation failures)
                int index = modelStateKeys.IndexOf( memberName );

                // Try and find an already existing error in the model state
                if( index == -1 || !modelStateValues[index].Errors.Any( i => i.ErrorMessage == error.ErrorMessage ) )
                {
                    // Add error
                    modelState.AddModelError( memberName, error.ErrorMessage );
                }
            }
        }
    }
}

ForceValidationModelBinderProvider:

/// <summary>
/// A custom model binder provider to provide a binder that forces an IValidatableObject to execute the Validate method, even when the ModelState is not valid.
/// </summary>
public class ForceValidationModelBinderProvider : IModelBinderProvider
{
    public IModelBinder GetBinder( Type modelType )
    {
        return new ForceValidationModelBinder();
    }
}

Global.asax.cs:

protected void Application_Start()
{
    // Register the force validation model binder provider
    ModelBinderProviders.BinderProviders.Clear();
    ModelBinderProviders.BinderProviders.Add( new ForceValidationModelBinderProvider() );
}

MVC4 Conditional HTML Attributes

MVC4 made one simple and yet awesome improvement to View rendering that I don’t think many people are aware of.

Have you ever had to conditionally add an attribute to an HTML element in your MVC View based on the presence of a variable? The typical use case is applying a CSS class to a div. Most of the time that code looks something like this:

<div @(myClass == null ? "" : "class=\"" + myClass + "\"")></div>

What a pain – not only to write but to read… This destroys the View’s readability and clutters the HTML up big time!

In MVC4, this process is much simpler. Just do this instead:

<div class="@myClass"></div>

That’s all you need. If myClass is null, it will ignore the class attribute and render without the class:

<div></div>

If myClass is not null, it will apply the class to the div:

<div class="test"></div>

This should work with other HTML element attributes also, though I haven’t tested them all myself. What a great little improvement!

Automatically Generate POCOs From DB With T4

The T4 template engine is insanely powerful. I didn’t really realize just how powerful it was until I had a use case for it today. I stood up a database with about 40 tables in it, and planned to use an ORM to access the database. To use the ORM, I needed POCOs (Plain Old C# Objects) that represented my database. Some of these tables had 30-50 or so columns and I didn’t want to code all of this by hand – it would take literally days.

Surprisingly, I got the whole thing done in about an hour with the help of the T4 template engine.

For those who are not familiar, T4 is a text template engine created by Microsoft which combines plain text and control logic to generate text output. In reality it’s a lot like how you use Razor or WebForms view engines to generate HTML; you can embed “code nuggets” almost exactly like you do in WebForms. The only real difference is that with T4 you’re creating a text file instead of a webpage.

To create a T4 template in Visual Studio 2010 or 2012, simply add a text file to your project… I called mine PocoGenerator.txt for example. Then, rename the file’s extension from “.txt” to “.tt” – the file will then be treated as a T4 Template by Visual Studio. Your output will appear in the code-behind .cs file attached to the .tt file you just created. In my scenario I wanted each of my POCOs to have their own file, so I did a bit of trickery to make that happen.

I wrote this nifty T4 template which connects to a database, queries all tables (ignoring sys tables), and then creates one POCO per table under a file named <tablename>.cs which is placed in a directory relative to the template’s location. Give this a go – you won’t be disappointed! And of course, if you need it to do more than I do, just modify it and make it your own!

<#@ template language="C#" hostspecific="true" debug="True" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="Microsoft.SqlServer.Smo" #>
<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="Microsoft.SqlServer.Management.Smo" #>
<#
    //**********************************************************************************************
    // This T4 generates POCOs from the specified DB and saves them to the specified folder which 
    // is relative to the template's location. One file per table/POCO.
    //**********************************************************************************************

    //****************************
    // DEFINE YOUR VARIABLES HERE
    //****************************
    // The SQL server name or IP
    string sqlServer = "9.9.9.9";
    // The SQL username
    string sqlLogin = "admin";
    // The SQL password
    string sqlPassword = "password";
    // The SQL database to generate the POCOs for
    string sqlDatabase = "MyDatabase";
    // The namespace to apply to the generated classes
    string classNamespace = "Your.Namespace.Here";
    // The destination folder for the generated classes, relative to this file's location.
    string destinationFolder = "PocoFolder";

    // Loop over each table and create a class file!
    Server server = new Server(sqlServer);
    server.ConnectionContext.LoginSecure = false;
    server.ConnectionContext.Login = sqlLogin;
    server.ConnectionContext.Password = sqlPassword;
    server.ConnectionContext.Connect();

    foreach (Table table in server.Databases[sqlDatabase].Tables)
    {
        // Skip sys tables
        if (table.Name.StartsWith("sys"))
        {
            continue;
        }
#>
using System;

namespace <#= classNamespace #>
{
    /// <summary>
    /// Represents a <#= table.Name #>.
    /// NOTE: This class is generated from a T4 template - you should not modify it manually.
    /// </summary>
    public class <#= table.Name #> 
    {
<# 
        // Keep count so we don't whitespace the last property/column
        int columnCount = table.Columns.Count;
        int i = 0;

        // Iterate all columns
        foreach (Column col in table.Columns)
        {
            i++;
            string propertyType = GetNetDataType(col.DataType.Name);

            // If we can't map it, skip it
            if (string.IsNullOrWhiteSpace(propertyType))
            {
                // Skip
                continue;
            }

            // Handle nullable columns by making the type nullable
            if (col.Nullable && propertyType != "string")
            {
                propertyType += "?";
            }
#>
        public <#= propertyType #> <#= col.Name #> { get; set; }
<#
            // Do we insert the space?
            if (i != columnCount)
            {
#>

<#
            }
#>
<#
        }
#>
    }
}      
<#
        // Write new POCO class to its own file
        SaveOutput(table.Name + ".cs", destinationFolder);
    } 
#>
<#+
    public static string GetNetDataType(string sqlDataTypeName)
    {
        switch (sqlDataTypeName.ToLower())
        {
            case "bigint":
                return "Int64";
            case "binary":
            case "image":
            case "varbinary":
                return "byte[]";
            case "bit":
                return "bool";
            case "char":
                return "char";
            case "datetime":
            case "smalldatetime":
                return "DateTime";
            case "decimal":
            case "money":
            case "numeric":
                return "decimal";
            case "float":
                return "double";
            case "int":
                return "int";
            case "nchar":
            case "nvarchar":
            case "text":
            case "varchar":
            case "xml":
                return "string";
            case "real":
                return "single";
            case "smallint":
                return "Int16";
            case "tinyint":
                return "byte";
            case "uniqueidentifier":
                return "Guid";
                
            default:
                return null;
        }
    }

    void SaveOutput(string outputFileName, string destinationFolder)
    {
        // Write to destination folder
        string templateDirectory = Path.Combine(Path.GetDirectoryName(Host.TemplateFile), destinationFolder);
        string outputFilePath = Path.Combine(templateDirectory, outputFileName);
        File.Delete(outputFilePath);
        File.WriteAllText(outputFilePath, this.GenerationEnvironment.ToString()); 

        // Flush generation
        this.GenerationEnvironment.Remove(0, this.GenerationEnvironment.Length);
    }
#>

Note that when the files are generated, they will not automatically be included in the project. You will have to add them manually as existing items.

This T4 Template supports regeneration, so anytime you update your database schema just re-run the template to create updated .cs files! Enjoy!

Web API Mapping QueryString/Form Input

If you’re using the Web API as part of the MVC4 framework, you may encounter a scenario in which you must map parameters of strange names to variables for which characters of the name would be illegal. That wasn’t very clear, so let’s do this by example. Consider part of the Facebook API:

Firstly, Facebook servers will make a single HTTP GET to your callback URL when you try to add or modify a subscription. A query string will be appended to your callback URL with the following parameters:

hub.mode – The string “subscribe” is passed in this parameter
hub.challenge – A random string
hub.verify_token – The verify_token value you specified when you created the subscription

Now if we wanted to use Web API to receive this data, we know that C# does not support the decimal character ‘.’ existing in variable names. So, how do we bind this querystring data to variables of a different name?

After a lot of searching, I discovered that the answer is surprisingly simple – just use the FromUriAttribute:

public string Get([FromUri(Name="hub.mode")]string mode, 
    [FromUri(Name="hub.challenge")]string challenge, 
    [FromUri(Name="hub.verify_token")]string verifyToken)
{
    /* method body */
}

Works like a charm!

When to Compile your Regex

In .NET, it is a common misconception that compiled Regex always operates faster than uncompiled Regex after the initial cost which is incurred at the time of instantiation only. This is not always true.

Recently I wrote a URL rewriter, similar to Helicon but a little more powerful and flexible. It allows you to define rules in a config file, and then rewrite a captured input string to an output string, replacing parts of the URL via Regex capture groups along the way. An example of the configuration looks like this:

<add original="^/(.*)/customer(.*)$" rewritten="/$1/cust$2" redirect="false" ignorecase="true" />

What the above says is that if my URL is anything, then “/customer” then optionally anything else, rewrite it to the “/cust” version of the URL with the original inputs applied to the outputs.

Now, considering myself to be an efficient developer, I have always pre-compiled my Regex by adding the RegexOptions.Compiled option to the constructor. My rewriter code that parsed my XML file and created Regex’s looked like this:

Regex rewriteRuleRegex = null;

// Determine if we ignore case
if (rewriteConfiguration.IgnoreCase)
{
    rewriteRuleRegex = new Regex(rewriteConfiguration.Original, RegexOptions.Compiled | RegexOptions.IgnoreCase);
}
else
{
    rewriteRuleRegex = new Regex(rewriteConfiguration.Original, RegexOptions.Compiled);
}

I had 144 rules in my file, and decided to performance test the URL writer against approximately 100 unique requests. The result was that it sucked, REALLY, REALLY badly, with 87% of the request lifecycle being spent on Regex.Replace!

Precompiled Sucks

Precompiled Sucks

That’s INSANE! 87% is COMPLETELY unacceptable! After all I’d heard about the .NET Regex engine being efficient, this was freaking terrible! I spent a day pulling my hair out and reading a ton of articles, when I came across one from Jeff Atwood about when to Precompile and when not to. So, I took the Precompile flag off of my code:

Regex rewriteRuleRegex = null;

// Determine if we ignore case
if (rewriteConfiguration.IgnoreCase)
{
    rewriteRuleRegex = new Regex(rewriteConfiguration.Original, RegexOptions.IgnoreCase);
}
else
{
    rewriteRuleRegex = new Regex(rewriteConfiguration.Original);
}

And re-ran my tests:

Precompiled Sucks

Precompiled Sucks

MUCH better.

So what I learned is that if you CONTROL the input (AKA if it’s a small set of input that you know in advance), precompiling is good. If you don’t control the input (such as user generated URLs that are sent to your application), DO NOT PRECOMPILE. EVER.

Generic Comparer

Have you ever had to write a comparer for a specific type, only to be frustrated when you needed to write a second and third comparer for other types? Fear not, a generic comparer can take care of this for you!

/// <summary>
/// Compares two objects of any type.
/// </summary>
/// <typeparam name="T">The type to be compared.</typeparam>
public class GenericComparer<T> : IComparer<T>
{
    // The compare method
    private readonly Func<T, T, int> _compareMethod = null;

    /// <summary>
    /// The constructor.
    /// </summary>
    /// <param name="compareMethod">The compare method.</param>
    public GenericComparer(Func<T, T, int> compareMethod)
    {
        // Sanitize
        if (compareMethod == null)
        {
            throw new ArgumentNullException("compareMethod");
        }

        _compareMethod = compareMethod;
    }

    /// <summary>
    /// Compares two objects.
    /// </summary>
    /// <param name="x">The first object.</param>
    /// <param name="y">The second object.</param>
    /// <returns>Less than 0 if x is less than y, greater than 
    /// 0 if x is greater than y, 0 if they are equal.</returns>
    public int Compare(T x, T y)
    {
        return _compareMethod(x, y);
    }
}

Just pass a method to the constructor that takes 2 objects of type T and returns an int, and you’re all set!

One More Thing About List Binary Search

I wanted to point people to this link at DotNetPearls:

http://www.dotnetperls.com/binarysearch

They do an excellent, quick demonstration of List<T>.BinarySearch and show a graph that really drives home how much faster it is for large lists than a regular traversal!

Make Mostly Read, Seldom-Written Lists Much More Efficient

One of the many things that I do at work is run a full-blown Search Engine which I also developed from scratch. This Search Engine feeds all product related information to our websites. A search index consists of a pre-computed collection of products, their properties, a list of words that are correctly spelled, and some pre-computed faceted/guided navigation. A search index, until this week, took up approximately 10.7 gigs of memory. This was becoming too large as we added new products every single day.

As of writing this, it now takes only 4.8 gigs of memory and is only slightly (1-3%) less performant than before. How did I do it? Believe it or not, a very simple data structure and algorithm change.

In the Search Engine, a product’s properties are a key-value pairing of strings… Things like “isInStock” “1” or “color” “red” etc. We store the properties in a collection, per product. The collection was originally:

Dictionary<string, HashSet<string>> _entityProperties;

The key of the Dictionary was the property name and the HashSet of strings were the values for that property name (property names are not a “unique” key – a product could have multiple colors for example). I initially chose this data structure because we have a heavy need for DIRECT lookups to property names and values. Methods like HasProperties(string propertyName) and HasProperty(string propertyName, string propertyValue) are essential to the search engine’s function, and need to be performant. Thus, I figured that a Dictionary and HashSet would be best, since both offer O(1) lookup times and the index is read from 10000x more often than it is written to. O(1 + 1) is pretty good when it comes to complexity.

It turns out that there was a simpler, better data structure for my goals which also satisfies the performance requirements of the aforementioned methods.

As you may or may not know (and I learned the hard way), a HashSet<T> is actually not very efficient when you have only a few items in it. A List<T> is actually more performant for small collections (4 or fewer objects with simple GetHashCode() methods, such as strings, in my testing). This is true even though your average lookup/read case goes from O(1) to (1/2n) since you must traverse the List to find your desired object. The reason that List is faster is that there is no hash key computation, and the List<T> is basically an elastic array and thus takes less memory and has less overhead than a HashSet<T> with the same number of objects in it. Since my product properties typically only consist of 2 or 3 values for a given property name, I changed my data structure to this:

Dictionary<string, List<string>> _entityProperties;

This shaved approximately 10% off of the memory footprint and brought my memory usage down to 9.6 gigs. The performance was basically identical in all performance tests. This was better than my HashSet, but still not great. I wanted to do better. I was sure that somehow I could do better.

I spent the good part of this week trying – and failing – to design a more efficient data structure than the above. I tried a string Trie with nodes that pointed to another Trie, I tried SortedList<TKey, TValue> instead of the above, and everything else that I could think of. Yet no matter what I did, the memory stayed the same and the performance was the same or worse. It sucked. I was still sure that somehow I could do better.

Finally, Wednesday morning, I had a thought in the shower (where I do my best thinking): two dimensional Arrays suck. They are well documented to, in general, have worse memory usage metrics than a one dimensional array (a quick Google will fill you in). A Dictionary of Lists is certainly a two dimensional jagged Array of sorts, and it wasn’t doing what I wanted in terms of memory. So, I took another approach and changed my data structure wildly – I flattened it out and made it one dimensional:

List<KeyValuePair<string, string>> _entityProperties;

Seems insane, right? I go from a Dictionary with an O(1) key lookup to a linear List of all keys and values stored together. And yet, it did the trick for my memory: it went from 9.6 gigs to 4.8 gigs. Half of the amount of memory used. I was stoked.

I saved this memory by both interning strings and taking advantage of the KeyValuePair being a struct. Structs are a lot more efficient than reference types when the object is small, and a KeyValuePair is indeed quite small.

A new problem needed solving, however. Each product has around 60-100 properties associated with it, and I needed them to be accessed efficiently and quickly with near-direct lookups. Traversing the [now giant] List was not acceptable in terms of performance.

As it stood, I went from an O(1 + 1) data structure (key and value lookup costs for Dictionary and HashSet) to an O(1 + 1/2n) data structure (Dictionary and List) and finally to an O(n) data structure (List). And to top it all off, the n in the 1/2n was 3 or 4 where the n in the flat List of KeyValuePair was between 60 and 100. Truly I was getting worse performance with each improvement – at least theoretically. Still, the allure of the memory savings was too great to ignore and I wanted to use this data structure.

It then hit me: why not use BinarySearch on the List<T> to look up items quickly and keep the List sorted while I add AND be able to check for duplicates before adding? It was certainly worth a shot, since binary search is an O(log n) algorithm which is an improvement over the List’s O(n) traversal. So, I modified my Add(string propertyName, string propertyValue) method to keep the List sorted as things were added to it. This is surprisingly easy to do.

*note that from here on out I’m simplifying my code greatly to basic concepts from what actually exists in order to avoid giving away trade secrets or violating my NDA and being fired*

public void Add(string propertyName, string propertyValue)
{   
    // TODO: null checks, etc.

    var keyValuePair = new KeyValuePair<string, string>(propertyName, propertyValue);

    // Add property name and value
    // First find the identical item if it exists
    var result = _entityProperties.BinarySearch(keyValuePair, _entityPropertiesComparer);
    // If result is >= 0, already exists, done
    if (result >= 0)
    {
        return;
    }

    // If it does not exist, a one's complement of the returned int tells us WHERE to insert to maintain the sort order
    _entityProperties.Insert(~result, keyValuePair);
}

The secret here is two-fold:

One: I created a custom KeyValuePair<string, string> comparer class that implements IComparer<KeyValuePair<string, string>> and basically does a case-insensitive string compare of first the key strings, then the value strings. This IComparer is required by the List’s BinarySearch method to determine the ordering of objects in the List.

Two: the BinarySearch method returns a very useful value: a simple integer. If the int is < 0, it means that the item was not found in the List. If it is >= 0, it means that the item was found at the index of the value. If it returns a negative integer, it means that it was not found, and also that the proper index to insert the item at in order to keep the List sorted is the one’s complement of the value. A super useful return type, indeed. This allows you to add your elements to a List while preserving an order, at the cost of your add being an O(log n) operation instead of a List’s usual O(1) add operation. However, if you don’t add things as much as you read the List (we only adjust the index once a day for example, but read it thousands of times per hour), this can be worthwhile. Additionally, you could add everything in O(1) time and then do a final List Sort in order to sort the List for a single O(log n) cost if the order of elements does not matter until you’re done adding everything. In my case, the order mattered as I added to the List because I did not ever want to add duplicates (same property name and value). The HashSet handles this for me – Lists do not.

So, now my add costs O(log n) instead of O(n), but the payoff is now my lookups cost O(log n) instead of O(n) as well. I adjusted my earlier mentioned HasProperty and HasProperties methods accordingly:

public List<string> GetSpecificPropertyValues(string propertyName)
{
    // TODO: null checks, etc.

    List<string> result = new List<string>();

    // Binary search the property name - null is the smallest value of string for comparison
    var keyValuePair = new KeyValuePair<string, string>(propertyName, null);
    // One's complement the start index
    var startIndex = ~_entityProperties.BinarySearch(keyValuePair, _entityPropertiesComparer);

    for (int i = startIndex; i < _entityProperties.Count; i++)
    {
        // Leave the loop when the property name no longer matches
        if (!string.Equals(propertyName, _entityProperties[i].Key, StringComparison.OrdinalIgnoreCase))
        {
            // Leave the loop
            break;
        }
                    
        result.Add(_entityProperties[i].Value);
    }

    return result;
}

public bool HasProperty(string propertyName, string propertyValue)
{
    // TODO: null checks, etc.

    // Binary search the property name
    var keyValuePair = new KeyValuePair<string, string>(propertyName, propertyValue);
    var startIndex = _entityProperties.BinarySearch(keyValuePair, _entityPropertiesComparer);
    return startIndex >= 0;
}

public bool HasProperties(string propertyName)
{
    // TODO: null checks, etc.

    // Binary search the property name
    var keyValuePair = new KeyValuePair<string, string>(propertyName, null);
    // One's complement the start index
    var startIndex = ~_entityProperties.BinarySearch(keyValuePair, _entityPropertiesComparer);
    if (startIndex >= _entityProperties.Count)
    {
        return false;
    }

    // Check that the next element matches the property name
    return string.Equals(propertyName, _entityProperties[startIndex].Key, StringComparison.OrdinalIgnoreCase);
}

Suddenly, I have the same “direct lookup” methods available as I did with my Dictionary and HashSet/List structure, but in a flat List with O(log n) complexity.

This yielded 50% less memory usage and only a 1-3% increase in performance times. A very acceptable trade for the Search Engine.

If you have a List<T> with a lot of objects in it, and performance is key to your application, consider using BinarySearch and/or Sort to access it in a much more efficient way. As long as you can create an IComparer<T> where T is your List objects type, you’ll have a more efficient List.

A Better MIME Mapping Stealer!

In the interest of self-improvement and sharing knowledge, I felt that I should share an update to my last post. I discovered a slightly better way to create the GetMimeMapping delegate/method via reflection that involves less casting and overhead, and is more Object Oriented in a sense. It allows the signature of the reflected method to be Func<string, string> instead of MethodInfo. Code below, note the use of Delegate.CreateDelegate(Type, MethodInfo):

/// <summary>
/// Exposes the Mime Mapping method that Microsoft hid from us.
/// </summary>
public static class MimeMappingStealer
{
    // The get mime mapping method
    private static readonly Func<string, string> _getMimeMappingMethod = null;

    /// <summary>
    /// Static constructor sets up reflection.
    /// </summary>
    static MimeMappingStealer()
    {
        // Load hidden mime mapping class and method from System.Web
        var assembly = Assembly.GetAssembly(typeof(HttpApplication));
        Type mimeMappingType = assembly.GetType("System.Web.MimeMapping");
        _getMimeMappingMethod = (Func<string, string>)Delegate.CreateDelegate(typeof(Func<string, string>), mimeMappingType.GetMethod("GetMimeMapping", 
            BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
            BindingFlags.NonPublic | BindingFlags.FlattenHierarchy));
    }

    /// <summary>
    /// Exposes the hidden Mime mapping method.
    /// </summary>
    /// <param name="fileName">The file name.</param>
    /// <returns>The mime mapping.</returns>
    public static string GetMimeMapping(string fileName)
    {
        return _getMimeMappingMethod(fileName);
    }
}