S
Stoitcho Goutsev \(100\) [C# MVP]
I'm not entirely sure about that - I don't think it's the C# compiler
which generates different IL code, but the JIT which generates
different native code. In the case of foreach, however, it's the C#
compiler generating different code.
It could be JIT as well. but the c# compilers also generates different code.
CIL has special instructions for working with arrays for example *ldlen* for
reading array length, indexing is also done in a different way and so on.
Ofcourse CLS not CILDo you mean implementing IEnumerable in a strongly-typed way as well as
with the normal "object" version (which would be explicitly
implemented)? Not sure what you mean by CIL compliant here - did you
mean CLS compliant? If so, which bit isn't CLS compliant? (I'm not
familiar with all the CLS rules - is it having two methods which differ
only in return type?)

I mean not implementing IEnumerable at all

The code that C# compilers genrates doesn't use neither IEnumberable nor
IEnumerator for the *foreach* loop. However in order the code to be CLS
compliant collections have to implement IEnumerable and the enumerator
object has to implement IEnumerator interface. One can take an advantage by
implementing explicitly those interfaces and provide strongly typed
enumeration as well.
To back up my words try the following
It's a silly collection of 3 integers, but there is no boxing.
------------------------
using System;
namespace ConsoleApplication
{
class Foo
{
int a;
int b;
int c;
//Class for the enumerator
public class MyOwnEnumerator
{
int index = -1;
Foo collection;
public int Current
{
get
{
if(index < 0 || index > 2)
throw new InvalidOperationException("XXX");
int res = 0;
switch(index)
{
case 0:
res = collection.a;
break;
case 1:
res = collection.b;
break;
case 2:
res = collection.c;
break;
}
return res;
}
}
public MyOwnEnumerator(Foo coll)
{
this.collection = coll;
}
public void Reset()
{
index = -1;
}
public bool MoveNext()
{
index++;
if(index > 2)
return false;
return true;
}
}
public Foo(int i0, int i1, int i2)
{
a = i0;
b = i1;
c = i2;
}
public MyOwnEnumerator GetEnumerator()
{
return new MyOwnEnumerator(this);
}
}
class Class1
{
[STAThread]
static void Main(string[] args)
{
Foo foo = new Foo(100, 200, 300);
foreach(int i in foo)
{
Console.WriteLine(i);
}
}
}
}