11using System ;
2+ using System . Collections . Generic ;
23using System . Linq ;
34using System . Linq . Expressions ;
45using System . Reflection ;
@@ -19,7 +20,26 @@ protected override bool CanMap(PreCompileArgument arg)
1920
2021 protected override bool CanInline ( Expression source , Expression ? destination , CompileArgument arg )
2122 {
22- return arg . MapType == MapType . Projection || ExpressionEx . CreateCountExpression ( source ) == null ;
23+ return arg . MapType == MapType . Projection ;
24+ }
25+
26+ protected override Expression TransformSource ( Expression source )
27+ {
28+ if ( ExpressionEx . CreateCountExpression ( source ) != null )
29+ return source ;
30+ var transformed = source ;
31+ var elemType = source . Type . ExtractCollectionType ( ) ;
32+ var type = typeof ( IEnumerable < > ) . MakeGenericType ( elemType ) ;
33+ if ( ! type . IsAssignableFrom ( source . Type ) )
34+ {
35+ var cast = typeof ( Enumerable ) . GetMethod ( nameof ( Enumerable . Cast ) ) !
36+ . MakeGenericMethod ( elemType ) ;
37+ transformed = Expression . Call ( cast , transformed ) ;
38+ }
39+
40+ var toList = typeof ( Enumerable ) . GetMethod ( nameof ( Enumerable . ToList ) ) !
41+ . MakeGenericMethod ( elemType ) ;
42+ return Expression . Call ( toList , transformed ) ;
2343 }
2444
2545 protected override Expression CreateInstantiationExpression ( Expression source , Expression ? destination , CompileArgument arg )
@@ -39,7 +59,12 @@ protected override Expression CreateBlockExpression(Expression source, Expressio
3959 {
4060 //Array.Copy(src, 0, dest, 0, src.Length)
4161 var method = typeof ( Array ) . GetMethod ( "Copy" , new [ ] { typeof ( Array ) , typeof ( int ) , typeof ( Array ) , typeof ( int ) , typeof ( int ) } ) ;
42- return Expression . Call ( method , source , Expression . Constant ( 0 ) , destination , Expression . Constant ( 0 ) , ExpressionEx . CreateCountExpression ( source ) ) ;
62+ var len = arg . UseDestinationValue
63+ ? Expression . Call ( typeof ( Math ) . GetMethod ( "Min" , new [ ] { typeof ( int ) , typeof ( int ) } ) ,
64+ ExpressionEx . CreateCountExpression ( source ) ,
65+ ExpressionEx . CreateCountExpression ( destination ) )
66+ : ExpressionEx . CreateCountExpression ( source ) ;
67+ return Expression . Call ( method , source , Expression . Constant ( 0 ) , destination , Expression . Constant ( 0 ) , len ) ;
4368 }
4469
4570 return CreateArraySet ( source , destination , arg ) ;
0 commit comments