I clearly understand "Pattern-based" approach that uses C# compiler when it dealing with the foreach
statement.
And from C# Language Specification (section 8.8.4) it is clear that first of all C# compiler tries to find GetEnumerator
method and only then tries to find IEnumerable<T>
and IEnumerable
interfaces.
But its unclear for me, why C# compiler treats string
separately (because the String
class contains a method GetEnumerator
that returns CharEnumerator
and it also implements IEnumerable<char>
and IEnumerable
interfces):
string s = "1234";
foreach(char c in s)
Console.WriteLine(c);
converts to
string s = "1234";
for(int i = 0; i < s.Length; i++)
Console.WriteLine(s[i]);
But I can't find any exceptions in Language Specification regarding the String
class. Could someone give some insights about this solution?
I tried with the C# 4 compiler. Here is the IL code for the previous code snippet:
IL_0000: ldstr "1234"
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: stloc.2
IL_0008: ldc.i4.0
IL_0009: stloc.3
IL_000A: br.s IL_001E
IL_000C: ldloc.2
IL_000D: ldloc.3
IL_000E: callvirt System.String.get_Chars
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: call System.Console.WriteLine
IL_001A: ldloc.3
IL_001B: ldc.i4.1
IL_001C: add
IL_001D: stloc.3
IL_001E: ldloc.3
IL_001F: ldloc.2
IL_0020: callvirt System.String.get_Length
IL_0025: blt.s IL_000C
The C programming language is the recommended language for creating embedded system drivers and applications. The availability of machine-level hardware APIs, as well as the presence of C compilers, dynamic memory allocation, and deterministic resource consumption, make this language the most popular.
%d is used to print decimal(integer) number ,while %c is used to print character . If you try to print a character with %d format the computer will print the ASCII code of the character.
Being a middle-level language, C reduces the gap between the low-level and high-level languages. It can be used for writing operating systems as well as doing application level programming. Helps to understand the fundamentals of Computer Theories.
C exists everywhere in the modern world. A lot of applications, including Microsoft Windows, run on C. Even Python, one of the most popular languages, was built on C. Modern applications add new features implemented using high-level languages, but a lot of their existing functionalities use C.
Good catch. I was aware that the compiler performed a similar optimization for arrays, but I didn't know that it did this for strings too.
The best I can get you is a call-out from the language specification that gives a compiler the right to stray from the 'canon' as long as it produces equivalent behaviour:
8.8.4 The foreach statement
[...] A foreach statement of the form
foreach (V v in x)
embedded-statement is then expanded to:
{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
embedded-statement
}
}
finally {
… // Dispose e
}
}
[...] An implementation is permitted to implement a given foreach-statement differently, e.g. for performance reasons, as long as the behavior is consistent with the above expansion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With