比较未知对象类型时,如何确保对字符串进行不区分大小写的比较?

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

我有一个 DataGridView,我正在编写一些通用代码来添加过滤器。列的基础数据类型可以是任何类型,但是如果它们是字符串,我希望过滤器使用不区分大小写的比较。

我还使用 Equals 方法而不是 == 运算符来确保它不只是进行参考比较。字符串 Equals 方法有一个重载让你选择 StringComparison 类型,但我不知道它是否会是一个字符串所以我只能访问 Equals object.

可用的方法

我尝试为 object 编写一个 Equals 扩展方法,它可以让我指定一个 StringComparison 类型。这个想法是,如果对象是字符串,那么它会在字符串对象上调用适当的 Equals 重载,否则它只会使用普通的 Equals 方法。但是,这似乎不起作用,因为我收到一个编译错误,指出我无法将该方法作为实例方法访问并且必须指定一个类型。我在下面包含了扩展方法,以防我在其中做错了什么……我确实仓促地写了它,但我不认为这是问题所在;我想我只需要找到另一种方法。

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);
    }
}

所以我正在寻找更好的方法,或者如果我只是在上面的代码中犯了错误,请告诉我。

编辑:

下面还有消费代码的样子。 _filters 只是具有一些属性的对象列表,例如您在下面看到的引用和项目是 IEnumerable<T>.

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

字符串比较位可以通过使用静态字符串 Equals 方法更简单:

return string.Equals(obj1.ToString(), obj2.ToString(), comparisonType);
  1. 您已经对 obj1 和 obj2 进行了空检查
  2. 将 obj1 转换为字符串实际上并不是将其转换为字符串,它只是意味着编译器允许您在其上使用类似字符串的方法。

编辑:为清楚起见,这将是我的完整静态方法:

public static class ObjectHelper
{
    public static bool EqualStrings(object obj1, object obj2, StringComparison comparisonType)
    {
        return string.Equals(obj1?.ToString(), obj2?.ToString(), comparisonType);
    }
}

我个人不会在对象上使用扩展方法 - 它会污染您的智能感知。为了简洁起见,我会使用 null 检查运算符。

您可以使用其他扩展方法,例如 IsEqual,然后在方法内部检查参数是否为字符串,以您喜欢的方式进行比较。

例如,类似下面的代码。我还没有测试功能,它只是演示这个想法:

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;
    }
}