private static Expression GetEnumerableSizeAccessor(EnumerableMappingFacts facts, Expression accessSourceCollection) { Expression accessSourceCollectionSize; // If it's an array, we want to access .Length to know its size, if it's ICollection<T>, we want .Count // and for anything else we have to use .Count(). if (facts.SourceIsArray) { // source.Length accessSourceCollectionSize = Expression.Property(accessSourceCollection, "Length"); } else { if (facts.SourceIsCollection) { var genericCollection = typeof(ICollection<>).MakeGenericType(facts.SourceElementType); var countProperty = genericCollection.GetProperty("Count"); // source.Count accessSourceCollectionSize = Expression.Property(accessSourceCollection, countProperty); } else { var genericEnumerable = typeof(IEnumerable<>).MakeGenericType(facts.SourceElementType); // source.Count() accessSourceCollectionSize = Expression.Call(null, countMethod.MakeGenericMethod(facts.SourceElementType), accessSourceCollection); } } return accessSourceCollectionSize; }
private EnumerableMappingFacts FindEnumerableMappingFacts( ParameterExpression source, ParameterExpression destination, ProposedTypeMapping complexTypeMapping) { var facts = new EnumerableMappingFacts(); if (complexTypeMapping.SourceMember != null) { facts.SourceEnumerableType = complexTypeMapping.SourceMember.PropertyOrFieldType; } else { facts.SourceEnumerableType = source.Type; } if (complexTypeMapping.DestinationMember != null) { facts.DestinationEnumerableType = complexTypeMapping.DestinationMember.PropertyOrFieldType; } else { facts.DestinationEnumerableType = destination.Type; } facts.DestinationElementType = CollectionTypeHelper.GetTypeInsideEnumerable(facts.DestinationEnumerableType); facts.SourceElementType = CollectionTypeHelper.GetTypeInsideEnumerable(facts.SourceEnumerableType); facts.CanAssignSourceElementsToDestination = CanAssignSourceElementToDestination(complexTypeMapping, facts.DestinationElementType, facts.SourceElementType); // If we're working with a Dictionary as the source if (facts.SourceElementType.IsGenericType && typeof(KeyValuePair<,>).IsAssignableFrom(facts.SourceElementType.GetGenericTypeDefinition())) { facts.SourceIsDictionaryType = true; } // If we're working with a Dictionary as the destination if (facts.DestinationElementType.IsGenericType && typeof(KeyValuePair<,>).IsAssignableFrom(facts.DestinationElementType.GetGenericTypeDefinition())) { facts.DestinationIsDictionaryType = true; } facts.SourceIsArray = facts.SourceEnumerableType.IsArray; var genericCollection = typeof(ICollection<>).MakeGenericType(facts.SourceElementType); if (genericCollection.IsAssignableFrom(facts.SourceEnumerableType)) { facts.SourceIsCollection = true; } else { facts.SourceIsIEnumerable = true; } facts.DestinationIsArray = facts.DestinationEnumerableType.IsArray; if (options.Conventions.PreserveDestinationListContents && IsCollectionType(facts.DestinationEnumerableType) && !facts.DestinationIsArray) { facts.PreserveDestinationContents = true; } if (IsListType(facts.SourceEnumerableType)) { facts.SourceIsList = true; } if (facts.DestinationEnumerableType.IsAssignableFrom(facts.SourceEnumerableType)) { facts.CanAssignSourceToDestination = true; } if (facts.DestinationEnumerableType.IsInterface) { facts.DestinationCouldBeArray = !facts.DestinationIsDictionaryType; } else if (facts.DestinationIsArray) { facts.DestinationCouldBeArray = true; } return facts; }