C# автоматически применять ToLower к параметру строки метода?

Есть ли способ заставить компилятор C# автоматически применять ToLower() (или любой другой вызов метода-манипулятора) к определенному параметру метода, прежде чем он будет использован внутри метода?

// дополнительная информация: его целью является использование словаря с регистронезависимым ключом. Очевидно, мой первый подход был совершенно неверным, поскольку я уже нашел совершенно другой подход, который касается самого словаря, а не ключа, к которому он обращается.

Виноват! Я должен был предоставить вам эту информацию. Таким образом, дальнейшие ответы не нужны. Во всяком случае, большое спасибо!

Лучший подход в данном конкретном случае: C# Dictionary: создание ключа без учета регистра с помощью объявлений

4 ответа

Решение

Нет, компилятор C# не сделает этого за вас (почему он должен быть приспособлен к такому конкретному требованию?), Но вы можете сделать это, написав простую оболочку struct вокруг string:

struct LowerCaseString
{
    public LowerCaseString(string value)
    {
        this.value = value.ToLower();
    }

    private readonly string value;

    public static implicit operator LowerCaseString(string value)
    {
        return new LowerCaseString(value);
    }

    public override string ToString()
    {
        return value;
    }

    … // perhaps implement IEquatable<>, IComparable<>, etc.
}

Оператор неявного преобразования позволяет вам писать код следующим образом:

Foo("Hello world.");

void Foo(LowerCaseString text)
{
    Console.WriteLine(text);
}

Хотя это работает, как и следовало ожидать, у этого подхода есть некоторые недостатки:

  • незначительное (возможно незначительное) снижение производительности, поскольку объект-оболочка должен быть создан вокруг вашей строки.

  • Для других пользователей вашего кода может быть неочевидным, что существует неявный оператор преобразования, поэтому они в конечном итоге пишут new LowerCaseString("Hello world.") вместо. Просмотр класса с помощью обозревателя объектов Visual Studio мог бы решить эту проблему, если бы ваша команда регулярно его использовала.

  • эта обертка не позволяет вам указать CultureInfo используется для .ToLower(), Вы хотите использовать CurrentCulture, или же InvariantCultureили какой-то другой?

Без использования какого-либо АОП, нет.

PostSharp - один из таких инструментов, но он поставляется с дополнительной сложностью, скрытым кодом и гораздо более высоким временем компиляции.

Гораздо проще применять ToLower на параметр непосредственно в методе, или оберните все вызовы метода с методом, который будет вызывать ToLower заранее.

Некоторые инструменты АОП, такие как PostSharp, могут сделать это.

Но проверьте дважды, что это действительно то, что вы хотите, и нет более простого и чистого способа.

Вы можете сделать это в соответствии с рекомендациями других - через АОП. Однако это станет слишком сложным и не будет стоить усилий (на мой взгляд), если дело только в пропуске строчных букв.

Вы должны предоставить больше информации по этому вопросу, но я считаю, что есть более простые способы достижения вашей цели. Взгляните на встроенные классы сравнения строк - возможно StringComparer.OrdinalIgnoreCase подойдет вашей цели, если вам нужны строчные строки для сравнения. Если вам нужно отобразить строки в нижнем регистре для пользователя, то это ответственность кода, который отображает строки, а не бизнес-логики.

Другие вопросы по тегам