Search code examples
c#linqstringlinq-to-objectstake

how to `.Take()` on a string and get a string at the end?


LINQ to Objects supports queries on string objects but when I use code such as below:

string SomeText = "this is some text in a string";
return SomeText.Take(6).ToString();

All I get is:

System.Linq.Enumerable+<TakeIterator>d__3a`1[System.Char]

This is discussed as an "accident" in this question but this is what I am actually trying to do and I cannot find it through search anywhere.

I know there are other ways to manipulate strings but then I also know you can do some really cool tricks with LINQ and I just would like to know if there is a way to trim a string to a certain length with LINQ?


Solution

  • There's no method built in to System.Linq to do this, but you could write your own extension method fairly easily:

    public static class StringExtensions
    {
        public static string ToSystemString(this IEnumerable<char> source)
        {
            return new string(source.ToArray());
        }
    }
    

    Unfortunately, because object.ToString exists on all .NET objects, you would have to give the method a different name so that the compiler will invoke your extension method, not the built-in ToString.

    As per your comment below, it's good to question whether this is the right approach. Because String exposes a lot of functionality through its public methods, I would implement this method as an extension on String itself:

    /// <summary>
    /// Truncates a string to a maximum length.
    /// </summary>
    /// <param name="value">The string to truncate.</param>
    /// <param name="length">The maximum length of the returned string.</param>
    /// <returns>The input string, truncated to <paramref name="length"/> characters.</returns>
    public static string Truncate(this string value, int length)
    {
        if (value == null)
            throw new ArgumentNullException("value");
        return value.Length <= length ? value : value.Substring(0, length);
    }
    

    You would use it as follows:

    string SomeText = "this is some text in a string";
    return SomeText.Truncate(6);
    

    This has the advantage of not creating any temporary arrays/objects when the string is already shorter than the desired length.