使用反射,从作为对象数组的属性中获取单个项 [英] Using reflection, get an individual item from a property that is an object array
问题描述
我有一个特殊设置的数据集 - 一个列类的数组,其属性为Name,DataType和Values
后一个属性是一个值数组,例如
I have a data set that is in a peculiar setup - an array of "column" classes with properties "Name", "DataType" and "Values"
The latter property is an array of values e.g.
public partial class UsageColumn {
private string nameField;
private string dataTypeField;
private object[] valuesField;
public string Name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}
public string DataType {
get {
return this.dataTypeField;
}
set {
this.dataTypeField = value;
}
}
public object[] Values {
get {
return this.valuesField;
}
set {
this.valuesField = value;
}
}
}
}
我目前正在将其转换为.NET集合: -
I am currently turning this into a .NET collection thus:-
public static List<TRecord> ConvertResultToList<TRecord>(object[] columns, int rowCount) where TRecord : DTO.IDataScopeDTOClass
{
List<TRecord> ret = new List<TRecord>();
// The object that we got in columns should have a property called Name and a property called DataType and Values[]
if (rowCount > 0)
{
if (columns.Count() > 0)
{
System.Reflection.PropertyInfo piName = columns[0].GetType().GetProperty(@"Name" );
System.Reflection.PropertyInfo piDataType = columns[0].GetType().GetProperty(@"DataType");
System.Reflection.PropertyInfo piValues = columns[0].GetType().GetProperty(@"Values");
System.Reflection.ConstructorInfo ciTarget = typeof(TRecord).GetConstructor(Type.EmptyTypes );
for (int i = 0; i < rowCount ; i++)
{
TRecord newValue = (TRecord)ciTarget.Invoke(null);
foreach (var thisColumn in columns)
{
string name = piName.GetValue(thisColumn).ToString();
string dataType = piDataType.GetValue(thisColumn).ToString();
object[] value = (object[])piValues.GetValue(thisColumn);
newValue.SetProperty(name, dataType, value[i]);
}
ret.Add(newValue);
}
}
}
return ret;
}
然而行 object [] value =(object [] )piValues.GetValue(thisColumn);
每次都复制整个数组。我如何获得index [i]的值?
However the line object[] value = (object[])piValues.GetValue(thisColumn);
is copying the whole array every time. How do I just get the value at index [i] ?
推荐答案
它不是复制数组;它只是获得对现有数组的引用。
您可以使用反射检索单个值,但这几乎肯定比将值转换为数组并直接访问它更慢:
It's not copying the array; it's just getting a reference to the existing array.
You could retrieve a single value using reflection, but that would almost certainly be slower than casting the value to an array and accessing it directly:
System.Reflection.MethodInfo miGet = piValues.PropertyType.GetMethod("Get");
...
object values = piValues.GetValue(thisColumn);
object value = miGet.Invoke(values, new object[] { i });
newValue.SetProperty(name, dataType, value);
其他评论:
拨打 GetType()
很慢;你应该缓存并重新使用 columns [0]的结果.GetType()
:
Other comments:
A call to GetType()
is slow; you should cache and re-use the result of columns[0].GetType()
:
Type columnType = columns[0].GetType();
System.Reflection.PropertyInfo piName = columnType.GetProperty(@"Name" );
System.Reflection.PropertyInfo piDataType = columnType.GetProperty(@"DataType");
System.Reflection.PropertyInfo piValues = columnType.GetProperty(@"Values");
您可以通过添加<反射来避免通过反射调用 TRecord
的构造函数code> new()对类型参数的约束:
You can avoid calling the TRecord
's constructor via reflection by adding a new()
constraint to the type parameter:
where TRecord : DTO.IDataScopeDTOClass, new()
...
TRecord newValue = new TRecord();
这篇关于使用反射,从作为对象数组的属性中获取单个项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!