Маленький способ получить первые 25 символов

Может ли кто-нибудь придумать более приятный способ сделать следующее:

public string ShortDescription
{
    get { return this.Description.Length <= 25 ? this.Description : this.Description.Substring(0, 25) + "..."; }
}

Я бы хотел просто сделать string.Substring (0, 25), но он выдает исключение, если строка меньше предоставленной длины.

Ответов (12)

Решение

Мне это так часто было нужно, я написал для этого метод расширения:

public static class StringExtensions
{
    public static string SafeSubstring(this string input, int startIndex, int length, string suffix)
    {
        // Todo: Check that startIndex + length does not cause an arithmetic overflow - not that this is likely, but still...
        if (input.Length >= (startIndex + length))
        {
            if (suffix == null) suffix = string.Empty;
            return input.Substring(startIndex, length) + suffix;
        }
        else
        {
            if (input.Length > startIndex)
            {
                return input.Substring(startIndex);
            }
            else
            {
                return string.Empty;
            }
        }
    }
}

если вам это нужно только один раз, это излишне, но если вам это нужно чаще, то это может пригодиться.

Изменить: добавлена ​​поддержка строкового суффикса. Передайте "...", и вы получите свои эллипсы на более коротких строках, или передайте строку. Пусто, без специальных суффиксов.

Мне кажется, что я очень придирчив, я бы заменил "..." ссылкой на сущность. "&hellip;"

return this.Description.Substring(0, Math.Min(this.Description.Length, 25));

Не играет роли ... . На самом деле твой путь, наверное, лучший.

Я думаю, что это разумный подход, хотя я бы порекомендовал внести некоторые коррективы.

  • Переместите магическое число на constили значение конфигурации
  • Используйте обычный ifусловный, а не тернарный оператор
  • Используйте string.Format("{0}...")вместо+ "..."
  • Есть только одна точка возврата из функции

Так:

public string ShortDescription
{
    get
    {
        const int SHORT_DESCRIPTION_LENGTH = 25;

        string _shortDescription = Description;

        if (Description.Length > SHORT_DESCRIPTION_LENGTH)
        {
            _shortDescription = string.Format("{0}...", Description.Substring(0, SHORT_DESCRIPTION_LENGTH));
        }

        return _shortDescription;
    }
}

Для более общего подхода вы можете перенести логику в метод расширения:

public static string ToTruncated(this string s, int truncateAt)
{
    string truncated = s;

    if (s.Length > truncateAt)
    {
        truncated = string.Format("{0}...", s.Substring(0, truncateAt));
    }

    return truncated;
}

Редактировать

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

Edit2

Для типографской правильности вы также можете рассмотреть возможность использования символа многоточия (…) вместо трех точек / точек / точек (...).

То, как вы это сделали, мне кажется нормальным, за исключением того, что я бы использовал магическое число 25, я бы использовал его как константу.

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

public static Take(this string s, int i)
{
    if(s.Length <= i)
        return s
    else
        return s.Substring(0, i) + "..."
}

public string ShortDescription
{
    get { return this.Description.Take(25); }
}

Один из способов сделать это:

int length = Math.Min(Description.Length, 25);
return Description.Substring(0, length) + "...";

Две строчки вместо одной, но покороче :).

Изменить: как указано в комментариях, это дает вам ... все время, поэтому ответ был неправильным. Исправляя это, мы возвращаемся к исходному решению.

На данный момент я думаю, что использование строковых расширений - единственный способ сократить код. И это имеет смысл только тогда, когда этот код повторяется хотя бы в нескольких местах ...

Я бы придерживался того, что у вас есть, но в качестве альтернативы, если у вас есть LINQ для объектов, вы могли бы

new string(this.Description.ToCharArray().Take(25).ToArray())

//And to maintain the ...
+ (this.Description.Length <= 25 ? String.Empty : "...")

Как говорили другие, вы, вероятно, захотите сохранить 25 в константе

Я не могу придумать ничего, но ваш подход может быть не лучшим. Вы добавляете логику представления в свой объект данных? В таком случае я предлагаю вам поместить эту логику в другое место, например, в статический класс StringDisplayUtils с GetShortStringMethod (int maxCharsToDisplay, string stringToShorten).

Однако этот подход тоже может быть не лучшим. А как насчет разных шрифтов и наборов символов? Вам нужно будет начать измерять фактическую длину строки в пикселях. Проверьте свойство AutoEllipsis в классе Winform Label (вам, вероятно, потребуется установить AutoSize в false, если вы используете это). Свойство AutoEllipsis, когда оно истинно, сократит строку и добавит символы "..." за вас.

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

//may return more than 25 characters depending on where in the string 25 characters is at
public string ShortDescription(string val)
{
    return Regex.Replace(val, @"(.{25})[^\s]*.*","$1...");
}
// stricter version that only returns 25 characters, plus 3 for ...
public string ShortDescriptionStrict(string val)
{
    return Regex.Replace(val, @"(.{25}).*","$1...");
}

У него есть приятное побочное преимущество - он не разрезает слово пополам, поскольку он всегда останавливается после первого пробельного символа после 25 символов. (Конечно, если вам нужно обрезать текст, поступающий в базу данных, это может быть проблемой.

Обратной стороной является то, что я уверен, что это не самое быстрое решение.

РЕДАКТИРОВАТЬ: заменено… на «…», так как не уверен, что это решение для Интернета!

Вы должны увидеть, можете ли вы ссылаться на Microsoft.VisualBasic DLL в свое приложение, чтобы вы могли использовать функцию «Left».

без .... это должно быть самым коротким:

public string ShortDescription
{
    get { return Microsoft.VisualBasic.Left(this.Description;}
}