0

I'm wondering why C# doesn't just return a string when I index into a string like this :

string x = "xyz";
var c = x[0]

4 Answers4

9

A string is made up of chars. If you're accessing a single element, as you're doing with the indexing operator, why should it return a string?

If you want a string to be returned you might want to use Substring.

mariosangiorgio
  • 5,520
  • 4
  • 32
  • 46
3

String is a class which takes an array of char to initialized itself, So when you try to fetch the element at some index it returns char. Check the string class enter image description here

Also see String class declaration.

public sealed class String : IComparable, ICloneable, IConvertible, IComparable<string>, IEnumerable<char>, IEnumerable, IEquatable<string>

Which is inherited by IEnumerable<char>.

Inside the string class there is a get property which returns the char when index is passed, see the image. Which clearly says that Gets the System.Char object at a specified position in the current System.String

enter image description here

public char this[int index] { get; }
Saket Choubey
  • 916
  • 6
  • 11
3

According to MSDN:

A String

Represents text as a sequence of UTF-16 code units.

A Char

Represents a character as a UTF-16 code unit.

It seems natural that if you index into a string (a sequence of UTF-16 code units) you get a char (a single UTF-16 code unit).

heijp06
  • 11,558
  • 1
  • 40
  • 60
1

I don't really agree with the answers and comments stating that it was natural to return a char. And no, a string in c# is not an array of char by definition (see the first answer to the duplicate, it is a class of it's own.

The only reason a char is returned is that the c# team decided to implement it that way. I don't know if they had a longer discussion about that or none at all. But I imagine that the reason for this implementation is that C# is more or less a successor of c/c++. And c/c++ developers have been highly used to this mental model of strings.

I rarely use the char type in c# and guess I could live well with a string implementation with indexers returning strings (and maybe some GetCharAt () method) but others might then wonder why it is implemented like that.

Community
  • 1
  • 1
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • Out of curiosity, what would make sense for `myString[i]` to return? Another string? An integer maybe would make sense but be rather difficult to use easily. As @Saket mentioned, the string class implements `IEnumerable`, so even if they decided to implement it differently than with an array of `char` the interface is simply designed to work with `char`s. – Jeremy Kato Jul 20 '16 at 20:13
  • 3
    Yes it is. If you look at the actual implementation, everything is marked as extern and unsafe and uses pointers everywhere, because it's a class to a native structure of chars. Look at how string.Compare even works, it boils down to `[SecurityCritical, SuppressUnmanagedCodeSecurity] [DllImport("QCall", CharSet = CharSet.Unicode)] private static extern int InternalCompareString(IntPtr handle, IntPtr handleOrigin, string localeName, string string1, int offset1, int length1, string string2, int offset2, int length2, int flags);` which in the CLR does a char by char comparison. – Dispersia Jul 20 '16 at 20:14
  • @JeremyKato `IEnumerable` has no indexer and would not depend on the indexers return type. – René Vogt Jul 20 '16 at 20:24
  • @Dispersia talking about an object oriented language, I should rarely care about the implementation details as the consumer of a class. The decision about the return type in question only depends on how you expect people to use the indexer, which leads to my point that most early c# users came from c-like languages, _expecting_ a char. – René Vogt Jul 20 '16 at 20:29
  • @RenéVogt Sorry if I'm not being clear. The point I'm getting at is if strings are built with `char`s, they use interfaces with `char`s, they have interface implementations that are meant to work with `char`s... Why doesn't it make sense to be able to access the `char`s by index? – Jeremy Kato Jul 20 '16 at 20:30
  • In fact, the implementation for all I care could be using integers or some arcane nonsense - working in `char` is a convenient way to access a string's contents, especially since the `char` data type is plainly made to work with text, which is what a string is also supposed to represent. – Jeremy Kato Jul 20 '16 at 20:32
  • @RenéVogt Yes, they could easily change it to be whatever they so choose for it to be with a simple cast, but a string -IS- just an array of chars, so no cast is needed, it just grabs it at the index to the pointer, which is the most efficient method of doing it. If the user wants some other way, create an extension method to grab it as whatever type the user wants :P – Dispersia Jul 20 '16 at 20:32
  • If you really want a `string` returned from indexing a string, just cast it to a string or use the infamous `.ToString()`. But, it's entirely counter-intuitive to return anything other than a `char` type. If I index a string, I expect to get a character back, not an integer, a string, or some other data type. Coming from the world of C and C++, this just makes sense. C: `char myArray[15] = "hello world"; printf("%c\n", myArray[2]); // prints 'l'`. C#: `string myString = "hello world"; Console.WriteLine(myString[2]); // prints 'l'` It's intuitive. – Ingenioushax Jul 20 '16 at 20:43
  • 1
    @Ingenioushax thanks for proving my point about the expectations of c developers :) and I know that a char can easily be casted to a string, but that was not the point of the question. – René Vogt Jul 20 '16 at 20:50
  • @RenéVogt: It absolutely highlights the expectations of C-based developers... After all, they are the foundation to the giants of whose shoulders we walk. But more to the point, a string can be instantiated using any of the following data types, `sbyte*, char*, char, and char[]`. So, in the end, it does look like strings are implemented using some form of an array or pointer, but are *NOT* arrays themselves, because String is a class, in turn, making it an object. – Ingenioushax Jul 20 '16 at 21:36