Search code examples
c#.netstringobjectcomparison

How to ensure case insensitive comparison on strings when comparing unknown object types?


I have a DataGridView that I am writing some generic code to add filters to. The underlying data types for the columns could be anything, however if they are strings I would like the filter to use a case insensitive comparison.

I also am using the Equals method rather than the == operator to make sure it's not just doing a reference comparison. The string Equals method has an overload to let you choose a StringComparison type, but I don't know whether it's going to be a string or not so I only have access to the Equals method available to an object.

I tried writing an Equals extension method for object that would let me specify a StringComparison type. The idea being that if the objects were strings then it would call the appropriate Equals overload on the string object, but otherwise it would just use the normal Equals method. However this does not seem to work as I get a compile error stating that I can't access the method as an instance method and must specify a type. I've included the extension method below in case I've done something wrong in it... I did write it hastily but I don't think it's the problem; I think I just have to find another way to do it.

public static class Extensions
{
    public static bool Equals(this object obj1, object obj2, StringComparison comparisonType)
    {
        if (obj1 == null && obj2 == null)
            return true;
        if (obj1 == null && obj2 != null)
            return false;
        if (obj1 != null && obj2 == null)
            return false;

        string s = obj1 as string;

        if (s != null)
        {
            var s2 = obj2 as string;
            return s2 != null && s.Equals(s2, comparisonType);
        }
        else
            return obj1.Equals(obj2);
    }
}

So I'm looking for either a better approach or if I simply made a mistake in the above code please let me know.

EDIT:

Also below is what consuming code looks like. _filters is just a list of objects with a few properties such as you see referenced below and items is IEnumerable<T>.

        foreach (var f in _filters)
        {
            items = items.Where(o => o[f.FieldName].Equals(f.Value, StringComparison.InvariantCultureIgnoreCase));
        }

Solution

  • You can use another extension method like IsEqual, then inside the method check if the parameter is string, compare in your preferred way.

    For example, something like the following code. I haven't tested the functionality, it's just demonstrating the idea:

    public static class ObjectExtesions
    {
        public static bool IsEqual(this object left, object right)
        {
            if (left == null && right == null)
                return true;
            if (left != null && right != null)
            {
                if (left is string && right is string)
                    return ((string)left).Equals((string)right,
                        StringComparison.InvariantCultureIgnoreCase);
                else
                    return left.Equals(right);
            }
            return false;
        }
    }