1

我正在从数据库数据创建一个通用对象:

object[] data = new object[dataReader.FieldCount];
dataReader.GetValues(data);
T t = (T)Activator.CreateInstance(typeof(T), data);

但是,第三行没有构造函数错误的类型。我想添加一个if

if (typeof(T).GetConstructor(data.TypesOf()) != null)

data.TypesOf()实际上是一个数组——Type[]包含data.

什么是data.TypesOf()真正有效的等价物?

还是我需要自己迭代data和构建它?

4

4 回答 4

6

我假设您object[]包含的值是例如 an int、 astring和 a float,并且您正在尝试解析 form 的构造函数public T(int,string,float)。要获取类型,您可以使用:

var types = Array.ConvertAll(data, x => x.GetType());

但这实际上对你没有多大帮助,因为这几乎是Activator.CreateInstance(typeof(T), data)已经尝试做的事情——所以如果Activator失败了,我看不出你会做得更好——除非关键不同之处在于构造函数是非公开的,您将提供一些BindingFlags.

不过,就个人而言,我建议按名称绑定比按位置绑定更容易。有像dapper这样的工具可以为您完成所有这些工作,让您可以简单地使用:

var data = conn.Query<SomeType>(sql, args).ToList();

例如:

int userId = 12345;
var users = conn.Query<User>("select * from Users where Id = @userId",
      new {userId}).SingleOrDefault();
于 2013-05-07T08:34:07.893 回答
1

据我了解,您正在尝试获取对象数组的元素类型。因此,您可以执行以下操作:

 var ctorArgsTypes = data.Select(d => d.GetType()).ToArray()

 var ctor = typeof(T).GetConstructor(ctorArgsType);

 // check if appropriate ctor exists
 if (ctor == null)
     throw something

 T t = (T)Activator.CreateInstance(typeof(T), data);
于 2013-05-07T08:33:43.243 回答
0

当您查看Activator.CreateInstance(Type, Object[])方法时,对于Object[]参数:

在数量、顺序和类型上匹配要调用的构造函数的参数的参数数组。如果 args 为空数组或 null,则调用不带参数的构造函数(默认构造函数)。

所以也许在你的情况下,你的data对象不是为每个值输入的(如果从数据库或文件中获取)。您需要找到一种在data数组中“键入”对象的方法。

于 2013-05-07T08:42:03.030 回答
0

只需使用Type.GetTypeArray(object[]).

https://msdn.microsoft.com/en-us/library/system.type.gettypearray(v=vs.110).aspx

于 2017-04-21T15:53:24.903 回答