문제

Please advise how can I build call of property Current and MoveNext of IEnumerable<byte>.

Target

I'd like to get something like:

var bytesEnumerator = byteArray.EnumerateArray();
var controlByte = bytesEnumerator.Current;
bytesEnumerator.MoveNext();

Variant 1

Here is code:

LocalBuilder lbBytesEnumerator = il.DeclareLocal(typeof (IEnumerator<byte>));
// Get enumerator over bytes
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, typeof(ByteConverter).GetMethod("EnumerateArray"), new[] { typeof(byte[]) } );
il.Emit(OpCodes.Stloc, lbBytesEnumerator);

.......
il.Emit(OpCodes.Ldloc_S, lbBytesEnumerator);
il.EmitCall(OpCodes.Call, typeof(IEnumerator<byte>).GetProperty("Current").GetGetMethod(), null);
LocalBuilder lbControlByte = il.DeclareLocal(propertyInfo.PropertyType);
il.Emit(OpCodes.Stloc, lbControlByte);


// Enumerator Move Next
il.Emit(OpCodes.Ldloc_S, lbBytesEnumerator);
il.EmitCall(OpCodes.Call, typeof(List<byte>.Enumerator).GetMethod("MoveNext"), null);
il.Emit(OpCodes.Pop);

Failed with:

{"Collection was modified; enumeration operation may not execute."}

Variant 2

And when I store enumerator by address (Ldloc_S -> Ldloca_S)

......
il.Emit(OpCodes.Ldloca_S, lbBytesEnumerator);
il.EmitCall(OpCodes.Call, typeof(IEnumerator<byte>).GetProperty("Current").GetGetMethod(), null);
LocalBuilder lbControlByte = il.DeclareLocal(propertyInfo.PropertyType);
il.Emit(OpCodes.Stloc, lbControlByte);

It fails with:

{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}

Update:

Enumerate array returns Enumerator based not on List but it's yielding results:

        for (var i = 0; i < array.Length; i++)
            yield return array[i];
도움이 되었습니까?

해결책 2

Fixed code:

                // Control byte
                il.Emit(OpCodes.Ldloc, lbBytesEnumerator);
                il.EmitCall(OpCodes.Callvirt, typeof(IEnumerator<byte>).GetProperty("Current").GetGetMethod(), null);
                LocalBuilder lbControlByte = il.DeclareLocal(propertyInfo.PropertyType);
                il.Emit(OpCodes.Stloc, lbControlByte);
                // Enumerator Move Next
                il.Emit(OpCodes.Ldloc, lbBytesEnumerator);
                il.EmitCall(OpCodes.Callvirt, typeof(IEnumerator).GetMethod("MoveNext"), null);
                il.Emit(OpCodes.Pop);

다른 팁

If you want to invoke your code, you have to work with Types and MethodInfos, not TypeBuilders and MethodBuilders.

So, you need to CreateType() and then use that Type and its method:

var generatedType = typeBuilder.CreateType();

var funcType = typeof(Func<,>).MakeGenericType(
generatedType, typeof(IEnumerable<string>));
var d = generatedType.GetMethod("MoveNext").CreateDelegate(funcType);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top