Example #1
0
        private CachingResult LoadEnumerable(ILGenerator ilGenerator, IEnumerable enumerable)
        {
            Assumes.NotNull(ilGenerator);
            Assumes.NotNull(enumerable);

            CachingResult result = CachingResult.SucceededResult;

            // We load enumerable as an array - this is the most compact and efficient way of representing it
            Type elementType = null;
            Type closedType = null;
            if (GenerationServices.TryGetGenericInterfaceType(enumerable.GetType(), GenerationServices.IEnumerableTypeofT, out closedType))
            {
                elementType = closedType.GetGenericArguments()[0];
            }
            else
            {
                elementType = typeof(object);
            }
            elementType = GenerationServices.NormalizeCollectionElementType(elementType);

            //
            // elem[] array = new elem[<enumerable.Count()>]
            //
            GenerationServices.LoadInt(ilGenerator, enumerable.Cast<object>().Count());
            ilGenerator.Emit(OpCodes.Newarr, elementType);
            // at this point we have the array on the stack

            int index = 0;
            foreach (object value in enumerable)
            {
                //
                //array[<index>] = value;
                //
                // load the array on teh stack again
                ilGenerator.Emit(OpCodes.Dup);
                GenerationServices.LoadInt(ilGenerator, index);
                result = result.MergeResult(this.LoadValue(ilGenerator, value));
                if (GenerationServices.IsBoxingRequiredForValue(value) && !elementType.IsValueType)
                {
                    ilGenerator.Emit(OpCodes.Box, value.GetType());
                }
                ilGenerator.Emit(OpCodes.Stelem, elementType);
                index++;
                // at this point we have the array on teh stack again
            }

            // the array is already on the stack - just exit

            return result;
        }
Example #2
0
 private static Type NormalizeCollectionElementType(Type type)
 {
     if (GenerationServices.IEnumerableType.IsAssignableFrom(type) && type != GenerationServices.StringType)
     {
         // the element is IEnumerable. we need to normalize it to be literally IEnumerable
         Type closedType = null;
         if (GenerationServices.TryGetGenericInterfaceType(type, GenerationServices.IEnumerableTypeofT, out closedType))
         {
             return GenerationServices.IEnumerableTypeofT.MakeGenericType(GenerationServices.NormalizeCollectionElementType(closedType.GetGenericArguments()[0]));
         }
         else
         {
             return typeof(IEnumerable<object>);
         }
     }
     else
     {
         return type;
     }
 }