Reputation: 6551
String.StartsWith(char)
and String.EndsWith(char)
are newly implemented in C# 7.0 .NET Core 2.0.
Why was String.Contains(char)
not implemented as well?
I usually hear the common argument to just create the String.Contains(char)
extension myself using String.IndexOf(c) != -1
. But I dislike creating simple extensions, especially if I'm going to create one for the sake for readability, which is what I believe these new overloads are for (and also why I approve of the changes :)).
Upvotes: 0
Views: 704
Reputation: 33178
Every "why isn't [something] a .NET Framework/Core/Standard [method|class|whatnot]?" comes down to one of two things:
.NET Framework is part of a very large engineering system, partially because it ships as part of Windows. This means that (prior to the advent of .NET Core) it's more optimized for large sweeping changes (like System.Linq, TPL, async/await, etc) than method-here/method-there. Individual methods that got added to existing types are largely due to "while writing a big feature we needed this and it made more sense to be public than [InternalsVisibleTo]". The consequence of this is that if no one thought a method was necessary at the time of the original class creation (and subsequent API review) it doesn't get added (especially if it's easy for someone to write themselves).
With .NET Core it's a lot easier to add something after the fact, so community feedback of "sheesh, I have to write this as an extension all the time" does result in some backfill, like string.StartsWith(char)
.
Every member has some cost associated with it. For a non-generic member on a non-generic type it's a small number of bytes on disk and a small amount of additional memory to load the library. For members on generic types there's an additional memory cost for each generic instantiation. (And I don't remember if generic methods have a cost per the number of different types that use them, or not.) For every member there's a maintenance cost. Sometimes the maintenance cost is low, but it's always there.
There's also a cost of "cognitive overload". This is when you go to write something and IntelliSense (or other similar tech) tells you that you have "too many" options, and you then have no idea which one you want. For two overloads, e.g. (DateTime start, DateTime end)
vs (DateTime start, TimeSpan duration)
it's easy to reason about, but when optional parameter overloads start popping up the matrix gets big. And when IntelliSense says something like "+21 more overloads" one's brain tends to want to shut down.
In the case of string.Contains(char)
it's probably #1. Probably no one thought it would be particularly useful when authoring string
for .NET Framework 1.0. And the person who filed https://github.com/dotnet/corefx/issues/4805 probably only needed StartsWith (or EndsWith) and the other end of the string was obvious, but Contains was just a little too far off their needs for them to think about (in fact, if you look at the issue, the word "contains" doesn't appear at all).
It's also possible that it was #2. I can certainly imagine the API review meeting where someone says something like "okay, so a string contains a 'q'... how is that useful? If it started with a q you might be doing subdirectory splitting. If it ended with a q you might be building a reverse string tree for solving word puzzles. But I can't imagine why you'd want to know it's there without knowing where it was...".
If it's a method that you feel is compelling, feel free to file an issue at https://github.com/dotnet/corefx/issues, following the API review process.
Upvotes: 2
Reputation: 14856
Because string.IndexOf
has been there forever.
But if you really think the name is that important to you:
public static class StringExtensions
{
public static bool Contains(this string self, string text)
=> self.IndexOf(text) >= 0;
}
Upvotes: 0
Reputation:
The System.Linq.Enumerable
static class already contains a generic Contains
function which works for arbitrary IEnumerable<T>
, including IEnumerable<char>
which string
implements.
In other words, it has already been implemented a long time ago. Just don't forget using System.Linq;
.
Upvotes: 7