Крошечный способ получить первые 25 символов - PullRequest
10 голосов
/ 27 февраля 2009

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

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

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

Ответы [ 12 ]

28 голосов
/ 27 февраля 2009

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

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

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

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

23 голосов
/ 27 февраля 2009
return this.Description.Substring(0, Math.Min(this.Description.Length, 25));

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

11 голосов
/ 27 февраля 2009
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); }
}
6 голосов
/ 27 февраля 2009

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

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

4 голосов
/ 27 февраля 2009

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

//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 символов. (Конечно, если вам это нужно для усечения текста, поступающего в базу данных, это может быть проблемой.

Недостаток, я уверен, что это не самое быстрое решение.

РЕДАКТИРОВАТЬ: заменено & hellip; с "...", так как не уверен, что это решение для сети!

3 голосов
/ 27 февраля 2009

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

public string ShortDescription
{
    get { return Microsoft.VisualBasic.Left(this.Description;}
}
1 голос
/ 27 февраля 2009

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

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

Есть две строки вместо одной, но более короткие:).

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

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

1 голос
/ 27 февраля 2009

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

  • Переместите магическое число в 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

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

0 голосов
/ 27 февраля 2009

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

0 голосов
/ 27 февраля 2009

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

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

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

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

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