提交 b73acfce 编写于 作者: V vosen

Add support for types with constructors matching the types pulled by data reader.

上级 f97241e5
......@@ -1497,12 +1497,31 @@ static List<FieldInfo> GetSettableFields(Type t)
int index = startBound;
ConstructorInfo specializedConstructor = null;
if (type.IsValueType)
{
il.Emit(OpCodes.Ldloca_S, (byte)1);
il.Emit(OpCodes.Initobj, type);
}
else
{
var types = new Type[length - startBound];
for (int i = startBound; i < startBound + length; i++)
{
types[i - startBound] = reader.GetFieldType(i);
}
var ctorWithParameters = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, types, null);
if (ctorWithParameters != null)
{
var ctorParams = ctorWithParameters.GetParameters();
for(int i =0; i< ctorParams.Length; i++)
{
if (!String.Equals(ctorParams[i].Name, names[i], StringComparison.OrdinalIgnoreCase))
break;
specializedConstructor = ctorWithParameters;
}
}
if(specializedConstructor == null)
{
var ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
if (ctor == null)
......@@ -1512,11 +1531,13 @@ static List<FieldInfo> GetSettableFields(Type t)
il.Emit(OpCodes.Newobj, ctor);
il.Emit(OpCodes.Stloc_1);
}
}
il.BeginExceptionBlock();
if(type.IsValueType)
{
il.Emit(OpCodes.Ldloca_S, (byte)1);// [target]
} else
}
else if(specializedConstructor == null)
{
il.Emit(OpCodes.Ldloc_1);// [target]
}
......@@ -1529,6 +1550,7 @@ static List<FieldInfo> GetSettableFields(Type t)
{
if (item.Property != null || item.Field != null)
{
if(specializedConstructor == null)
il.Emit(OpCodes.Dup); // stack is now [target][target]
Label isDbNullLabel = il.DefineLabel();
Label finishLabel = il.DefineLabel();
......@@ -1587,6 +1609,8 @@ static List<FieldInfo> GetSettableFields(Type t)
{
il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType }));
}
if (specializedConstructor == null)
{
if (item.Property != null)
{
il.Emit(OpCodes.Callvirt, item.Property.Setter); // stack is now [target]
......@@ -1595,6 +1619,7 @@ static List<FieldInfo> GetSettableFields(Type t)
{
il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
}
}
il.Emit(OpCodes.Br_S, finishLabel);
......@@ -1614,6 +1639,8 @@ static List<FieldInfo> GetSettableFields(Type t)
il.Emit(OpCodes.Newobj, memberType.GetConstructor(new[] { nullUnderlyingType }));
}
}
if (specializedConstructor == null)
{
if (item.Property != null)
{
if (type.IsValueType)
......@@ -1629,13 +1656,24 @@ static List<FieldInfo> GetSettableFields(Type t)
{
il.Emit(OpCodes.Stfld, item.Field); // stack is now [target]
}
}
il.Emit(OpCodes.Br_S, finishLabel); // stack is now [target]
il.MarkLabel(isDbNullLabel); // incoming stack: [target][target][value]
if (specializedConstructor != null)
{
Type itemType = item.Property != null ? item.Property.Type : item.Field.FieldType;
if (itemType.IsValueType)
il.Emit(OpCodes.Initobj, itemType);
else
il.Emit(OpCodes.Ldnull);
}
else
{
il.Emit(OpCodes.Pop); // stack is now [target][target]
il.Emit(OpCodes.Pop); // stack is now [target]
}
if (first && returnNullIfFirstMissing)
{
......@@ -1656,6 +1694,10 @@ static List<FieldInfo> GetSettableFields(Type t)
}
else
{
if (specializedConstructor != null)
{
il.Emit(OpCodes.Newobj, specializedConstructor);
}
il.Emit(OpCodes.Stloc_1); // stack is empty
}
il.MarkLabel(allDone);
......
......@@ -33,29 +33,21 @@ public class ConcreteOrder : Order
}
}
class NoDefualtConstructor
class NoDefaultConstructor
{
public NoDefualtConstructor(int a)
public NoDefaultConstructor(int a)
{
A = a;
}
public int A { get; set; }
}
public void EnsureNoConstructorGivesNiceError()
public void TestNoDefaultConstructor()
{
try
{
connection.Query<NoDefualtConstructor>("select 1 A").First();
}
catch(InvalidOperationException e)
{
e.Message.IsEqualTo("A parameterless default constructor is required to allow for dapper materialization");
NoDefaultConstructor nodef = connection.Query<NoDefaultConstructor>("select 1 A").First();
nodef.A.IsEqualTo(1);
}
}
// http://stackoverflow.com/q/8593871
public void TestAbstractInheritance()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册