Title is the entire question. Can someone give me a reason why this happens?

Yes – because it does begin with the empty string. Indeed, the empty string logically occurs between every pair of characters.

Put it this way: what definition of “starts with” could you give that would preclude this? Here’s a simple definition of “starts with” that doesn’t:

“x starts with y if the first `y.Length`

characters of x match those of y.”

An alternative (equivalent) definition:

“x starts with y if `x.Substring(0, y.Length).Equals(y)`

“

I will try to elaborate on what Jon Skeet said.

Let’s say x, y and z are strings and + operator is in fact concatenation, then:

If we can split z to write z = x + y that means that z starts with x.

Because every string z can be split to z = “” + z it follows that every string starts with “”.

So, because (“” + “abcd”) == “abcd” it follows that “abcd” starts with “”

This method compares the value parameter to the substring at the beginning of this string that is the same length as value, and returns a value that indicates whether they are equal. **To be equal, value must be an empty string (Empty), a reference to this same instance, or match the beginning of this instance.**

true if the character sequence represented by the argument is a prefix of the character sequence represented by this string; false otherwise. **Note also that true will be returned if the argument is an empty string** or is equal to this String object as determined by the equals(Object) method.

I’ll start with a related fact that is easier to understand.

**The empty set is a subset of every set.**

Why? The definition of *subset* states that `A`

is a subset of `B`

if every element of `A`

is an element of `B`

. Conversely, `A`

is not a subset of `B`

if there is an element of `A`

that is not an element of `B`

.

Now fix a set `B`

. I’ll establish that the empty set is a subset of `B`

. I’ll do this by showing that it is not the case that the empty set is not a subset of `B`

. If the empty set were not a subset of `B`

then I could find an element of the empty set that is not in `B`

. But the empty set does not have any elements and thus I can not find an element that is not in `B`

. Therefore, it is not the case that the empty set is not a subset of `B`

. Thus, the empty set must be a subset of `B`

.

**Any string starts with the empty string.**

First, we must agree on our definition of *starts with*. Let `s`

and `t`

be `string`

s We say that `s`

*starts with* `t`

if `s.Length >= t.Length`

and the first `t.Length`

characters of `t`

match those of `s`

. That is, `s.Length >= t.Length`

and for every `Int32 index`

such that `0 <= index < t.Length`

, `s[index] == t[index]`

is true. Conversely, we would say that `s`

does not start with `t`

if the statement

`s.Length < t.Length`

or `s.Length >= t.Length`

and there is an `Int32 index`

such that `0 <= index < t.Length`

and `s[index] != t[index]`

is true. In plain English, `s`

is shorter than `t`

, or, if not, there is a character in `t`

not matching the character as the same position in `s`

.

Now fix a string `s`

. I’ll establish that `s`

starts with the empty string. I’ll do this by showing that it is not the case that `s`

does not start with the empty string. If `s`

does not start with the empty string then `s.Length < String.Empty.Length`

or `s.Length >= String.Empty.Length`

and there is an `Int32 index`

such that `0 <= index < String.Empty.Length`

. But `s.Length >= 0`

and `String.Empty.Length`

is equal to zero so it is impossible for `s.Length < String.Empty.Length`

to be true. Similarly, since “String.Empty.Length`is equal to zero, there is no`

Int32 index`satisfying`

0 <= index < String.Empty.Length`. Therefore

`s.Length < String.Empty.Length`

or `s.Length >= String.Empty.Length`

and there is an `Int32 index`

such that `0 <= index < String.Empty.Length`

is false. Therefore, it is not the case that `s`

does not start with the empty string. Thus, `s`

must start with the empty string.

The following is an implementation of *starts with* coded as an extension to `string`

.

```
public static bool DoStartsWith(this string s, string t) {
if (s.Length >= t.Length) {
for (int index = 0; index < t.Length; index++) {
if (s[index] != t[index]) {
return false;
}
}
return true;
}
return false;
}
```

The above two bolded facts are examples of vacuously true statements. They are true by virtue of the fact that the statements defining them (*subset* and *starts with*) are universal quantifications over empty universes. There are no elements in the empty set, so there can not be any elements of the empty set not in some other fixed set. There are no characters in the empty string, so there can not be a character as some position in the empty string not matching the character in the same position in some other fixed string.

Let’s just say `"abcd".StartsWith("")`

returns false.

if so then what does the following expression eval to, true or false:

```
("abcd".Substring(0,0) == "")
```

it turns out that evals to true, so the string does start with the empty string ;-), or put in other words, the substring of “abcd” starting at position 0 and having 0 length equals the empty string “”. Pretty logical imo.

In C# this is how the specification tells it to react;

To be equal, value must be an empty string (Empty), a reference to this same instance, or match the beginning of this instance.

Why does “abcd”.StartsWith(“”) return true?

THE REAL ANSWER:

It has to be that way otherwise you’d have the case where

```
"".startsWith("") == false
"".equals("") == true
but yet
"a".startsWith("a") == true
"a".equals("a") == true
```

and then we’d have Y2K all over again because all the bank software that depends on equal strings starting with themselves will get our accounts mixed up and suddenly Bill Gates will have my wealth and I’d have his, and damn it! Fate just isn’t that kind to me.

The first N characters of the two strings are identical. N being the length of the second string, i.e. zero.

Just for the record, `String.StartsWith()`

internally calls the method `System.Globalization.CultureInfo.IsPrefix()`

which makes the following check explicitly:

```
if (prefix.Length == 0)
{
return true;
}
```

Because a string begins well with “nothing”.

If you think of it in regular expressions terms, it makes sense.

Every string (not just “abcd”, also “” and “sdf\nff”) ,

returns true when evaluating the regular expression of ‘starts with empty string’.

In C#, the reason it returns `true`

is that the developers specifically coded for it.

If you check out the source code, you’ll find specific logic to handle an empty string:

```
public Boolean StartsWith(String value)
{
return StartsWith(value, StringComparison.CurrentCulture);
}
public Boolean StartsWith(String value, StringComparison comparisonType)
{
...
if (value.Length == 0)
{
return true;
}
```