Как обеспечить сравнение строк без учета регистра при сравнении неизвестных типов объектов? - PullRequest
2 голосов
/ 06 февраля 2020

У меня есть DataGridView, в который я пишу некоторый обобщенный код c, для добавления фильтров. Базовые типы данных для столбцов могут быть любыми, однако, если они являются строками, я бы хотел, чтобы фильтр использовал сравнение без учета регистра.

Я также использую метод Equals вместо оператора == чтобы убедиться, что это не просто сравнение ссылок. У метода string Equals есть перегрузка, позволяющая выбрать тип StringComparison, но я не знаю, будет ли он строкой или нет, поэтому у меня есть только доступ к методу Equals, доступному для object.

Я попытался написать метод расширения Equals для object, который позволил бы мне указать тип 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));
        }

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Вы можете использовать другой метод расширения, например IsEqual, затем внутри метода проверьте, является ли параметр строкой, сравните по своему предпочтению.

Например, что-то вроде следующего кода. Я не проверял функциональность, он просто демонстрирует идею:

0 голосов
/ 06 февраля 2020

Бит сравнения строк может быть намного проще, если использовать метод stati c string Equals:

return string.Equals(obj1.ToString(), obj2.ToString(), comparisonType);
  1. Вы уже проверили null obj1 и obj2
  2. Casting obj1, поскольку строка на самом деле не преобразует ее в строку, это просто означает, что компилятор позволяет использовать для нее строковые методы.

Редактировать: для ясности, это будет моя полная оценка c method:

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

Лично у меня не было бы метода расширения для объекта - он загрязнит ваш разум. И я бы использовал краткие операторы проверки для краткости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...