private static IEnumerable <Expression> GetArrayBounds(Expression source, Type destinationType) { var destRank = destinationType.GetArrayRank(); if (!source.Type.IsArray) { for (int i = 0; i < destRank - 1; i++) { yield return(Expression.Constant(1)); } yield return(ExpressionEx.CreateCountExpression(source, true)); } else { var srcRank = source.Type.GetArrayRank(); var method = typeof(Array).GetMethod("GetLength", new[] { typeof(int) }); for (int i = srcRank; i < destRank; i++) { yield return(Expression.Constant(1)); } for (int i = 0; i < srcRank; i++) { yield return(Expression.Call(source, method, Expression.Constant(i))); } } }
protected override Expression CreateInstantiationExpression(Expression source, Expression destination, CompileArgument arg) { var destinationElementType = arg.DestinationType.ExtractCollectionType(); var count = ExpressionEx.CreateCountExpression(source, false); var listType = arg.DestinationType.GetTypeInfo().IsInterface ? typeof(List <>).MakeGenericType(destinationElementType) : arg.DestinationType; if (count == null) { return(Expression.New(listType)); //new List<T>() } var ctor = (from c in listType.GetConstructors() let args = c.GetParameters() where args.Length == 1 && args[0].ParameterType == typeof(int) select c).FirstOrDefault(); if (ctor == null) { return(Expression.New(listType)); //new List<T>() } else { return(Expression.New(ctor, count)); //new List<T>(count) } }
protected override Expression CreateInstantiationExpression(Expression source, Expression?destination, CompileArgument arg) { var destinationElementType = arg.DestinationType.ExtractCollectionType(); return(Expression.NewArrayBounds( destinationElementType, ExpressionEx.CreateCountExpression(source, true))); //new TDestinationElement[count] }
protected override Expression CreateInstantiationExpression(Expression source, Expression?destination, CompileArgument arg) { var listType = arg.DestinationType; if (arg.DestinationType.GetTypeInfo().IsInterface) { var dict = arg.DestinationType.GetDictionaryType(); if (dict != null) { var dictArgs = dict.GetGenericArguments(); listType = typeof(Dictionary <,>).MakeGenericType(dictArgs); } else if (arg.DestinationType.IsAssignableFromList()) { var destinationElementType = arg.DestinationType.ExtractCollectionType(); listType = typeof(List <>).MakeGenericType(destinationElementType); } else // if (arg.DestinationType.IsAssignableFromSet()) { var destinationElementType = arg.DestinationType.ExtractCollectionType(); listType = typeof(HashSet <>).MakeGenericType(destinationElementType); } } var count = ExpressionEx.CreateCountExpression(source, false); if (count == null) { return(Expression.New(listType)); //new List<T>() } var ctor = (from c in listType.GetConstructors() let args = c.GetParameters() where args.Length == 1 && args[0].ParameterType == typeof(int) select c).FirstOrDefault(); if (ctor == null) { return(Expression.New(listType)); //new List<T>() } else { return(Expression.New(ctor, count)); //new List<T>(count) } }
protected override Expression CreateBlockExpression(Expression source, Expression destination, CompileArgument arg) { if (source.Type.IsArray && source.Type.GetArrayRank() == 1 && source.Type.GetElementType() == destination.Type.GetElementType() && source.Type.GetElementType() !.IsPrimitiveKind()) { //Array.Copy(src, 0, dest, 0, src.Length) var method = typeof(Array).GetMethod("Copy", new[] { typeof(Array), typeof(int), typeof(Array), typeof(int), typeof(int) }); var len = arg.UseDestinationValue ? Expression.Call(typeof(Math).GetMethod("Min", new[] { typeof(int), typeof(int) }) !, ExpressionEx.CreateCountExpression(source) !, ExpressionEx.CreateCountExpression(destination) !) : ExpressionEx.CreateCountExpression(source); return(Expression.Call(method !, source, Expression.Constant(0), destination, Expression.Constant(0), len !)); } return(CreateArraySet(source, destination, arg)); }
protected override Expression TransformSource(Expression source) { if (ExpressionEx.CreateCountExpression(source) != null) { return(source); } var transformed = source; var elemType = source.Type.ExtractCollectionType(); var type = typeof(IEnumerable <>).MakeGenericType(elemType); if (!type.IsAssignableFrom(source.Type)) { var cast = typeof(Enumerable).GetMethod(nameof(Enumerable.Cast)) ! .MakeGenericMethod(elemType); transformed = Expression.Call(cast, transformed); } var toList = typeof(Enumerable).GetMethod(nameof(Enumerable.ToList)) ! .MakeGenericMethod(elemType); return(Expression.Call(toList, transformed)); }
protected override Expression CreateBlockExpression(Expression source, Expression destination, CompileArgument arg) { if (source.Type.IsArray && source.Type.GetArrayRank() == destination.Type.GetArrayRank() && source.Type.GetElementType() == destination.Type.GetElementType() && source.Type.GetElementType().IsPrimitiveKind()) { //Array.Copy(src, 0, dest, 0, src.Length) var method = typeof(Array).GetMethod("Copy", new[] { typeof(Array), typeof(int), typeof(Array), typeof(int), typeof(int) }); return(Expression.Call(method, source, Expression.Constant(0), destination, Expression.Constant(0), ExpressionEx.CreateCountExpression(source, true))); } else { return(CreateArraySet(source, destination, arg)); } }