我试图在运行时动态传递类的类型。以下代码在代码部分给出错误:
object newObject Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName));
data.Read<newObject>();
我也试过
data.Read<Type.GetType(t.GetGenericArguments()[0].FullName)>();
这是完整的方法:
public object FetchMultipleRecordSet(string storedProcedure, IList<QueryParameter> parameterCollection, object dataList)
{
if (!string.IsNullOrEmpty(storedProcedure))
{
using (SqlConnection sql = CreateDatabaseConnection())
{
DynamicParameters dynamicParameter = ConvertToDynamicParameters(parameterCollection);
var data = sql.QueryMultiple(storedProcedure, dynamicParameter, null, null, commandType: CommandType.StoredProcedure);
PropertyInfo[] properties = dataList.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
Type t = property.PropertyType;
if (t.BaseType == null && t.IsGenericType && t.Namespace == "System.Collection.Generic")
{
//property.SetValue(data.Read());
object newObject = Activator.CreateInstance(Type.GetType(t.GetGenericArguments()[0].FullName));
data.Read<>();
}
else if (t.Namespace != "System")
{
//typeCollection.Add(Type.GetType(t.FullName));
}
}
}
}
return dataList;
}
这是我想要使用的视图模型:
public class ResultCollection
{
public IList<ShortCodeList> ShortCodeListCollection { get; set; }
public DateTime CurrentDate { get; set; }
public UserMembershipPlan UserMembershipPlanRecord { get; set; }
public IList<EmailRecipients> EmailRecipientsCollection { get; set; }
}
我需要将类型传递给data.Read(),以便通用形式的属性可以与结果集一起映射。如果我通过&#34; newObject&#34;或&#34; Type.GetType(t.GetGenericArguments()[0] .FullName)&#34;它仍然给我错误。这可能看起来很笨拙,但我认为它应该有用。
答案 0 :(得分:2)
目前,针对精巧的类型化API使用泛型。有一个无类型的API,但您需要进行自己的成员映射。要通过类型调用泛型方法,需要在泛型方法MakeGenericMethod和Invoke上使用MethodInfo。通过在代码中添加填充方法,还可以使用dynamic
来欺骗它,类似于:
dynamic template = ... // activator etc
Evil(template, otherArgs...);
Evil<T>(T template, otherArgs...) {
use some <T> method etc here
}
作为一个更完整的例子,以下工作:
public void TypeBasedViaDynamic()
{
Type type = GetSomeType();
dynamic template = Activator.CreateInstance(type);
dynamic actual = CheetViaDynamic(template,
"select @A as [A], @B as [B]", new { A = 123, B = "abc" });
((object)actual).GetType().IsEqualTo(type);
int a = actual.A;
string b = actual.B;
a.IsEqualTo(123);
b.IsEqualTo("abc");
}
T CheetViaDynamic<T>(T template, string query, object args)
{
return connection.Query<T>(query, args).SingleOrDefault();
}
static Type GetSomeType()
{
return typeof(SomeType);
}
public class SomeType
{
public int A { get;set; }
public string B { get;set; }
}
请注意,这仅从Type
开始,并通过虚拟实例(通过Activator
)和dynamic
填充实例。不漂亮,但它的工作原理。但是,我也只是将一些更改推送到接受Type
实例作为参数的dapper,使得以下内容也起作用 - 无需这些黑客:
public void TypeBasedViaType()
{
Type type = GetSomeType();
dynamic actual = connection.Query(type,
"select @A as [A], @B as [B]", new { A = 123, B = "abc" }
).FirstOrDefault();
((object)actual).GetType().IsEqualTo(type);
int a = actual.A;
string b = actual.B;
a.IsEqualTo(123);
b.IsEqualTo("abc");
}
还有多个网格读者:
public void TypeBasedViaTypeMulti()
{
Type type = GetSomeType();
dynamic first, second;
using(var multi = connection.QueryMultiple(
"select @A as [A], @B as [B]; select @C as [A], @D as [B]",
new { A = 123, B = "abc", C = 456, D = "def" }))
{
first = multi.Read(type).Single();
second = multi.Read(type).Single();
}
((object)first).GetType().IsEqualTo(type);
int a = first.A;
string b = first.B;
a.IsEqualTo(123);
b.IsEqualTo("abc");
((object)second).GetType().IsEqualTo(type);
a = second.A;
b = second.B;
a.IsEqualTo(456);
b.IsEqualTo("def");
}
请注意,这些新API示例中的dynamic
纯粹是为了方便测试; dynamic
不是该方法的重要组成部分。