17
\$\begingroup\$

This is an extension method to get a string that is truncated to a maximum length.

Any comments?

public static class StringExtensions
{
    public static string WithMaxLength(this string value, int maxLength)
    {
        if (value == null)
        {
            return null;
        }

        return value.Substring(0, Math.Min(value.Length, maxLength));
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ No, that's pretty much as good as it gets. There isn't much to say about this few code. \$\endgroup\$ – Jeroen Vannevel Aug 15 '15 at 12:16
  • \$\begingroup\$ Isn't it a bit inconsistent that WithMaxLength(null, 1) doesn't throw an exeption whereas WithMaxLength("", 1) would? \$\endgroup\$ – Konrad Morawski Aug 15 '15 at 19:16
  • \$\begingroup\$ @KonradMorawski neither would throw an exception. WithMaxLength(null, 1) would return null and WithMaxLength("", 1) would return ""... \$\endgroup\$ – Jakob Aug 15 '15 at 19:30
  • 1
    \$\begingroup\$ For what purpose do you truncate? How do you define length? Which kind of sequences do you want to keep intact (e.g. code-points or even text-elements)? \$\endgroup\$ – CodesInChaos Aug 16 '15 at 9:11
  • 1
    \$\begingroup\$ @CodesInChaos I have a legacy system where settings for actions are stored in a table with a long description. Then when a action is performed the description is saved in several places with different maximum lengths in the database and I just want to save what is room for and discard the rest. \$\endgroup\$ – Jakob Aug 17 '15 at 16:13
29
\$\begingroup\$

If you're using C# 6.0, I believe you can drop the null-check:

public static string WithMaxLength(this string value, int maxLength)
{
    return value?.Substring(0, Math.Min(value.Length, maxLength));
}

Other than that, it's like Jeroen said: that's pretty much as good as it gets.

The class and parameter naming is exactly as I'd have it, and the name of the extension method is decent, although I'd try to find a name that better indicates that truncation will occur when value is longer than maxLength... but WithMaxLength isn't a bad name.

\$\endgroup\$
  • 4
    \$\begingroup\$ I agree with you regarding naming. The method truncates a string, if needed, and the naming should reflect that. If I were to use something named WithMaxLength, I might expect the returned to string to actually have maxLength even if I pass string.Empty as the input value. \$\endgroup\$ – Rick Davin Aug 15 '15 at 15:07
  • 1
    \$\begingroup\$ "Keep" or "Left" are common names for such a method. \$\endgroup\$ – ToolmakerSteve Mar 7 at 9:48
9
\$\begingroup\$

There is an inconsistency - negative values of maxLength would be forgiven for value being null, but cause an exception for every other input (since Substring would throw an ArgumentOutOfRangeException).

There's two possible approaches that remove this inconsistency - fail fast

public static string WithMaxLength(this string value, int maxLength)
{
    if (maxLength < 0)
    {
       throw new ArgumentOutOfRangeException("maxLength must be equal to or greater than 0");
    }
    // ...

Or ignore negative values for both cases:

public static string WithMaxLength(this string value, int maxLength)
{
    if (value == null)
    {
        return null;
    }
    if (maxLength < 0)
    {
        return "";
    }
    return value.Substring(0, Math.Min(value.Length, maxLength));
}

Personally I'd be inclined to choose the former - maxLength being smaller than 0 could be a symptom of a problem (implementation error) that we wouldn't want to sweep under the carpet. It's also consistent with the way Substring itself behaves.

\$\endgroup\$
6
\$\begingroup\$

Well, Mat's Mug already gave the only improvement for the code in the extension-method I could find, using the conditional-member-access operator.

Aside from that, there's only the methods name. Which is far too long and awkward.
Truncate has a nice ring to it, and everybody understands it.

public static class StringExtensions
{
    public static string Truncate(this string value, int maxLength)
    {
        return value?.Substring(0, Math.Min(value.Length, maxLength));
    }
}
\$\endgroup\$
5
\$\begingroup\$

Per Mat's Mug's answer:

I'd try to find a name that better indicates that truncation will occur when value is longer than maxLength... but WithMaxLength isn't a bad name.

I disagree that the method's name is the place to do this. It's not. And WithMaxLength is a perfectly fine name.

But... that truncation occurs should be documented. I'm not sure what's available exactly for C#, but most all languages have a format for showing in-IDE documentation.

I've been told the C# version of this looks something like this:

<summary>
This function does something.
<param name="string">The string to do things with</param>
</summary>

We should certainly add this sort of documentation to our method to be clear on exactly what happens with the method. I think any other sort of name for the method itself goes beyond to descriptive and ventures into the realm of too verbose (and this is coming from someone who writes Objective-C...).

\$\endgroup\$
  • \$\begingroup\$ I think you're looking for the <Remarks> tag. \$\endgroup\$ – RubberDuck Aug 15 '15 at 17:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.