public static object CastCollection <T>( this IEnumerable <T> values, Type desiredType, bool asArray) { var listType = GenericListType.MakeGenericType(desiredType); var asList = Activator.CreateInstance(listType); var addMethod = listType.GetMethod("Add"); if (addMethod == null) { throw new InvalidOperationException( $"{listType} has no 'Add' method?!" ); } values.ForEach(v => { addMethod.Invoke( asList, new object[] { v } ); }); return(asArray ? ConvertToArray(asList) : asList); }
public static object AsVector(IEnumerable seq, Symbol type) { var t1 = (Type)GetType(type); var t2 = GenericListType.MakeGenericType(t1); var c = t2.GetConstructors(); var x = c[2].Invoke(new object[] { AsArray(seq, type) }); return(x); }
static void WriteSerializerList(TypeBuilder typeBuilder, ILGenerator il, Type type, MethodInfo valueMethod, int?valueLocalIndex = null, OpCode?valueLocalOpCode = null) { //var arguments = type.GetGenericArguments(); bool useGenericArguments; var listType = GetGenericListType(type, out useGenericArguments);//arguments.Length > 0 ? arguments[0] : ObjectType; var genericListType = GenericListType.MakeGenericType(listType); var iEnumerableType = !useGenericArguments?GenericIEnumeratorType.MakeGenericType(listType) : null; var hasIEnumerable = iEnumerableType != null; var enumeratorType = hasIEnumerable ? iEnumerableType : GenericListEnumerator.MakeGenericType(listType); var enumeratorLocal = il.DeclareLocal(enumeratorType); var moveNextType = hasIEnumerable ? EnumeratorType : enumeratorType; var entryLocal = il.DeclareLocal(listType); var startEnumeratorLabel = il.DefineLabel(); var moveNextLabel = il.DefineLabel(); var endEnumeratorLabel = il.DefineLabel(); if (valueLocalIndex != null) { il.Emit(valueLocalOpCode.Value, valueLocalIndex.Value); } if (valueLocalIndex == null) { il.Emit(OpCodes.Ldarg_2); } if (valueMethod != null) { il.Emit(OpCodes.Callvirt, valueMethod); } if (type.Name == "IList`1") { il.Emit(OpCodes.Castclass, genericListType); } il.Emit(OpCodes.Callvirt, (hasIEnumerable ? type : genericListType).GetMethod("GetEnumerator")); il.Emit(OpCodes.Stloc_S, enumeratorLocal.LocalIndex); il.BeginExceptionBlock(); il.Emit(OpCodes.Br, startEnumeratorLabel); il.MarkLabel(moveNextLabel); il.Emit(hasIEnumerable ? OpCodes.Ldloc : OpCodes.Ldloca_S, enumeratorLocal.LocalIndex); il.Emit(hasIEnumerable ? OpCodes.Callvirt : OpCodes.Call, enumeratorLocal.LocalType.GetProperty("Current") .GetGetMethod()); il.Emit(OpCodes.Stloc, entryLocal.LocalIndex); if (listType.IsComplexType()) { if (listType.IsCollectionType()) { WriteSerializerClass(typeBuilder, il, listType, 1, null, callerType: listType, valueLocalIndex: entryLocal.LocalIndex, valueLocalOpCode: OpCodes.Ldloc); } else { WriteSerializerCallClassMethod(typeBuilder, il, listType, OpCodes.Ldloc, entryLocal.LocalIndex, 1, null, needClassHeader: false); } } else { WriteSerializerBytesToStream(il, listType, OpCodes.Ldloc, entryLocal.LocalIndex, 1, null, isTargetCollection: true); } il.MarkLabel(startEnumeratorLabel); il.Emit(hasIEnumerable ? OpCodes.Ldloc : OpCodes.Ldloca_S, enumeratorLocal.LocalIndex); il.Emit(hasIEnumerable ? OpCodes.Callvirt : OpCodes.Call, moveNextType.GetMethod("MoveNext", MethodBinding)); il.Emit(OpCodes.Brtrue, moveNextLabel); il.Emit(OpCodes.Leave, endEnumeratorLabel); il.BeginFinallyBlock(); il.Emit(hasIEnumerable ? OpCodes.Ldloc : OpCodes.Ldloca_S, enumeratorLocal.LocalIndex); if (!hasIEnumerable) { il.Emit(OpCodes.Constrained, enumeratorLocal.LocalType); } il.Emit(OpCodes.Callvirt, IDisposableDisposeMethod); il.EndExceptionBlock(); il.MarkLabel(endEnumeratorLabel); }
static void WriteDeserializerList(TypeBuilder typeBuilder, ILGenerator il, Type type, int tag, MethodInfo setMethod, int?itemLocalIndex = null) { bool useGenericArguments; var itemType = GetGenericListType(type, out useGenericArguments);//type.GetGenericArguments()[0]; if (useGenericArguments && GenericIListType.IsAssignableFrom(type.GetGenericTypeDefinition())) { type = GenericListType.MakeGenericType(itemType); } var lengthLocal = il.DeclareLocal(typeof(int)); var listLocal = il.DeclareLocal(type); var itemLocal = il.DeclareLocal(itemType); var indexLocal = il.DeclareLocal(typeof(int)); var startLabel = il.DefineLabel(); var endLabel = il.DefineLabel(); var hasLocalList = setMethod != null || itemLocalIndex != null; il.Emit(OpCodes.Ldarg_2); il.Emit(OpCodes.Ldarg_3); il.Emit(OpCodes.Ldc_I4, tag); il.Emit(OpCodes.Call, GetCollectionLengthMethod); il.Emit(OpCodes.Stloc, lengthLocal); if (hasLocalList) { var lengthCtor = type.GetConstructor(CtorCapacityTypes); if (lengthCtor != null) { il.Emit(OpCodes.Ldloc, lengthLocal.LocalIndex); il.Emit(OpCodes.Newobj, lengthCtor); il.Emit(OpCodes.Stloc, listLocal.LocalIndex); } else { il.Emit(OpCodes.Newobj, type.GetConstructor(Type.EmptyTypes)); il.Emit(OpCodes.Stloc, listLocal.LocalIndex); } } il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc, indexLocal.LocalIndex); il.Emit(OpCodes.Br, startLabel); il.MarkLabel(endLabel); WriteDeserializerReadValue(typeBuilder, il, itemType, 1, itemLocal.LocalIndex); if (hasLocalList) { il.Emit(OpCodes.Ldloc, listLocal.LocalIndex); } else { il.Emit(OpCodes.Ldarg_1); } il.Emit(OpCodes.Ldloc, itemLocal.LocalIndex); il.Emit(OpCodes.Callvirt, type.GetMethod("Add", new[] { itemType })); il.Emit(OpCodes.Ldloc, indexLocal.LocalIndex); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc, indexLocal.LocalIndex); il.MarkLabel(startLabel); il.Emit(OpCodes.Ldloc, indexLocal.LocalIndex); il.Emit(OpCodes.Ldloc, lengthLocal.LocalIndex); il.Emit(OpCodes.Blt, endLabel); if (setMethod != null && itemLocalIndex == null) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldloc, listLocal.LocalIndex); il.Emit(OpCodes.Callvirt, setMethod); } else if (itemLocalIndex != null) { il.Emit(OpCodes.Ldloc, listLocal.LocalIndex); il.Emit(OpCodes.Stloc, itemLocalIndex.Value); } }