我在 C# 中遇到了 System.Reflection 的一些问题。我正在从数据库中提取数据并在 JSON 字符串中检索该数据。我已经使用反射实现了将 JSON 中的数据处理到我自己声明的对象中的实现。但是,由于我通常会得到一个包含 50 - 100 个对象的数组的 JSON 字符串,因此我的程序运行速度非常慢,因为我使用反射的循环。
我听说反射很慢,但不应该这么慢。我觉得我的实现有些不对劲,因为我有一个不同的项目,我在其中使用 JSON.NET 序列化程序并用反射实例化我的对象有点不同,反射在相同的输出上运行得很好(不到一秒),而我的慢程序需要50 个对象大约需要 10 秒。
以下是我用来存储数据的课程
class DC_Host
{
public string name;
public void printProperties()
{
//Prints all properties of a class usign reflection
//Doesn't really matter, since I'm not usign this for processing
}
}
class Host : DC_Host
{
public string asset_tag;
public string assigned;
public string assigned_to;
public string attributes;
public bool? can_print;
public string category;
public bool? cd_rom;
public int? cd_speed;
public string change_control;
public string chassis_type;
//And some more properties (around 70 - 80 fields in total)
您将在下面找到我将信息处理为存储在列表中的对象的方法。JSON 数据存储在一个字典中,该字典包含另一个字典,用于在 JSON 输入中定义的每个数组对象。反序列化 JSON 会在几毫秒内发生,所以那里不应该有问题。
public List<DC_Host> readJSONTtoHost(ref Dictionary<string, dynamic> json)
{
bool array = isContainer();
List<DC_Host> hosts = new List<DC_Host>();
//Do different processing on objects depending on table type (array/single)
if (array)
{
foreach (Dictionary<string, dynamic> obj in json[json.First().Key])
{
hosts.Add(reflectToObject(obj));
}
}
else
{
hosts.Add(reflectToObject(json[json.First().Key]));
}
return hosts;
}
private DC_Host reflectToObject(Dictionary<string,dynamic> obj)
{
Host h = new Host();
FieldInfo[] fields = h.GetType().GetFields();
foreach (FieldInfo f in fields)
{
Object value = null;
/* IF there are values that are not in the dictionairy or where wrong conversion is
* utilised the values will not be processed and therefore not inserted into the
* host object or just ignored. On a later stage I might post specific error messages
* in the Catch module. */
/* TODO : Optimize and find out why this is soo slow */
try
{
value = obj[convTable[f.Name]];
}
catch { }
if (value == null)
{
f.SetValue(h, null);
continue;
}
// Het systeem werkt met list containers, MAAAR dan mogen er geen losse values zijn dus dit hangt
// zeer sterk af van de implementatie van Service Now.
if (f.FieldType == typeof(List<int?>)) //Arrays voor strings,ints en bools dus nog definieren
{
int count = obj[convTable[f.Name]].Count;
List<int?> temp = new List<int?>();
for (int i = 0; i < count; i++)
{
temp.Add(obj[convTable[f.Name]][i]);
f.SetValue(h, temp);
}
}
else if (f.FieldType == typeof(int?))
f.SetValue(h, int.Parse((string)value));
else if (f.FieldType == typeof(bool?))
f.SetValue(h, bool.Parse((string)value));
else
f.SetValue(h, (string)value);
}
Console.WriteLine("Processed " + h.name);
return h;
}
我不确定 JSON.NET 在后台使用反射的实现是什么,但我假设他们使用我缺少的东西来优化他们的反射。