Skip to content

Commit

Permalink
Object to primitive type is always converted using Convert class.
Browse files Browse the repository at this point in the history
  • Loading branch information
satano committed Dec 7, 2016
1 parent 48cd143 commit d2bacfa
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/Mapster.Tests/Mapster.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
<Compile Include="Classes\TypeTestClass.cs" />
<Compile Include="WhenCloningConfig.cs" />
<Compile Include="WhenCompilingConfig.cs" />
<Compile Include="WhenConvertingFromObjects.cs" />
<Compile Include="WhenCreatingConfigInstance.cs" />
<Compile Include="WhenIgnoringConditionally.cs" />
<Compile Include="WhenMappingDerived.cs" />
Expand Down
39 changes: 39 additions & 0 deletions src/Mapster.Tests/WhenConvertingFromObjects.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Shouldly;

namespace Mapster.Tests
{
[TestFixture]
class WhenConvertingFromObjects
{

#region TestClasses

public class SimplePoco
{
public int Int32 { get; set; }
public long Int64 { get; set; }
}

#endregion

[Test]
public void Int32_In_Object_Is_Converted_To_Int64()
{
var dictionaryData = new Dictionary<string, object>
{
{ "Int32", 32 },
{ "Int64", 64 }
};

var poco = dictionaryData.Adapt<SimplePoco>();
poco.Int32.ShouldBe(32);
poco.Int64.ShouldBe(64L);
}
}
}
76 changes: 35 additions & 41 deletions src/Mapster/Utils/ReflectionUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ internal static class ReflectionUtils
{
private static readonly Type _stringType = typeof (string);

// Primitive types with their conversion methods from System.Convert class.
private static Dictionary<Type, string> _primitiveTypes = new Dictionary<Type, string>() {
{ typeof(bool), "ToBoolean" },
{ typeof(short), "ToInt16" },
{ typeof(int), "ToInt32" },
{ typeof(long), "ToInt64" },
{ typeof(float), "ToSingle" },
{ typeof(double), "ToDouble" },
{ typeof(decimal), "ToDecimal" },
{ typeof(ushort), "ToUInt16" },
{ typeof(uint), "ToUInt32" },
{ typeof(ulong), "ToUInt64" },
{ typeof(byte), "ToByte" },
{ typeof(sbyte), "ToSByte" },
{ typeof(DateTime), "ToDateTime" }
};


#if NET4
public static Type GetTypeInfo(this Type type) {
return type;
Expand Down Expand Up @@ -55,8 +73,8 @@ public static bool IsCollection(this Type type)
public static Type ExtractCollectionType(this Type collectionType)
{
var enumerableType = collectionType.GetGenericEnumerableType();
return enumerableType != null
? enumerableType.GetGenericArguments()[0]
return enumerableType != null
? enumerableType.GetGenericArguments()[0]
: typeof (object);
}

Expand All @@ -69,7 +87,7 @@ public static Type GetInterface(this Type type, Func<Type, bool> predicate)
{
if (predicate(type))
return type;

return type.GetInterfaces().FirstOrDefault(predicate);
}

Expand Down Expand Up @@ -138,6 +156,11 @@ public static Expression BuildUnderlyingTypeConvertExpression(Expression source,
}
}

if (IsObjectToPrimitiveConversion(srcType, destType))
{
return CreateConvertMethod(_primitiveTypes[destType], srcType, destType, source);
}

//try using type casting
try
{
Expand All @@ -152,49 +175,20 @@ public static Expression BuildUnderlyingTypeConvertExpression(Expression source,
throw new InvalidOperationException("Cannot convert immutable type, please consider using 'MapWith' method to create mapping");

//using Convert
if (destType == typeof (bool))
return CreateConvertMethod("ToBoolean", srcType, destType, source);

if (destType == typeof (int))
return CreateConvertMethod("ToInt32", srcType, destType, source);

if (destType == typeof (long))
return CreateConvertMethod("ToInt64", srcType, destType, source);

if (destType == typeof (short))
return CreateConvertMethod("ToInt16", srcType, destType, source);

if (destType == typeof (decimal))
return CreateConvertMethod("ToDecimal", srcType, destType, source);

if (destType == typeof (double))
return CreateConvertMethod("ToDouble", srcType, destType, source);

if (destType == typeof (float))
return CreateConvertMethod("ToSingle", srcType, destType, source);

if (destType == typeof (DateTime))
return CreateConvertMethod("ToDateTime", srcType, destType, source);

if (destType == typeof (ulong))
return CreateConvertMethod("ToUInt64", srcType, destType, source);

if (destType == typeof (uint))
return CreateConvertMethod("ToUInt32", srcType, destType, source);

if (destType == typeof (ushort))
return CreateConvertMethod("ToUInt16", srcType, destType, source);

if (destType == typeof (byte))
return CreateConvertMethod("ToByte", srcType, destType, source);

if (destType == typeof (sbyte))
return CreateConvertMethod("ToSByte", srcType, destType, source);
if (_primitiveTypes.ContainsKey(destType))
{
return CreateConvertMethod(_primitiveTypes[destType], srcType, destType, source);
}

var changeTypeMethod = typeof (Convert).GetMethod("ChangeType", new[] {typeof (object), typeof (Type)});
return Expression.Convert(Expression.Call(changeTypeMethod, Expression.Convert(source, typeof (object)), Expression.Constant(destType)), destType);
}

private static bool IsObjectToPrimitiveConversion(Type sourceType, Type destinationType)
{
return (sourceType == typeof(object)) && _primitiveTypes.ContainsKey(destinationType);
}

public static MemberExpression GetMemberInfo(Expression method)
{
var lambda = method as LambdaExpression;
Expand Down

0 comments on commit d2bacfa

Please sign in to comment.