Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
            }
        }