C# vs. Java: StartsWith

The C# and Java languages are quite similar, but there are many differences. Recently, while porting a large system written in Java to C# I was reminded how the two languages differ in their string starts-with methods.

For the Java starts-with method, there are two signatures:

boolean startsWith(String prefix)

boolean startsWith(String prefix, int toffset) 

So if s = “FooBarBizFooBar” then s.startsWith(“FooB”) returns true and s.startsWith(“foob”) returns false because the comparison is case-sensitive.

And s.startsWith(“Bar”,3) means does s have a “Bar” starting at index 3 and returns true.

But there is some really weird behavior too, especially with the empty string. Some examples:

s.startsWith(""); // true ?!

s.startsWith("Bar", -1); // false
s.startsWith("Bar", 99); // false

s.startsWith(null, 3); // throws

s.startsWith("", 3); // true WTH?!
s.startsWith("", -9); // false ?!
s.startsWith("", 99); // false ?!

s.startsWith("BarBarBarBarBarBar", 3); // false

If the offset number is less than 0 or greater than the last index in s, startsWith returns true. If the offset is in range, startsWith(“”, ) returns true.

The C# starts-with method has three signatures. The first is a regular method, the other two deal with case and CultureInfo for non-English.

bool StartsWith(string value)

So I wanted to implement a custom C# starts-with method that works like the Java-style starts-with method that accepts an offset. My C# version of the Java style starts-with is:

private static bool JavaStyleStartsWith(string s,
  string prefix, int tOffset)
  if (s == null)
    throw new Exception("badness");

  if (s == "" && prefix == "")
    if (tOffset == 0)
      return true;
      return false;

  if (s == "" && prefix != "")
    return false;

  if (tOffset = s.Length)
    return false;

  int len = prefix.Length;
  if (len > s.Length)
    return false;
  if (len > s.Length - tOffset)
    return false;

  int idx = s.IndexOf(prefix, tOffset, len);
  if (idx >= 0) return true;
  else return false;

I essentially use the C# IndexOf method. I begin by dealing with empty strings. The C# IndexOf method isn’t as tolerant of out-of-range offset values so I do some checking of the offset value before sending it to the C# IndexOf method.

I have to use the overload of IndexOf that limits the numbers of characters to compare because the IndexOf without the limit will search through the end of s and give an incorrect result in some cases (if the target string doesn’t start at the offset but does occur further down the string).


Bottom line: writing a Java-style String starts-with method for C# was quite a bit trickier than I thought it’d be.

This entry was posted in Miscellaneous. Bookmark the permalink.