【发布时间】:2015-12-02 15:14:50
【问题描述】:
假设我有一个原始值,我需要使用反射将其分配给某个字段。我确定该字段具有相同的原始值类型。
是否可以在不装箱的情况下以某种方式设置此值?
void SetFloat(object o, string name, float val)
{
var type = o.GetType();
var fld = type.GetField(name);
fld.SetValue(o, val /*boxing happens here*/);
}
附:这实际上与延迟无关,而与可能的 GC 压力有关。我正在使用 Unity3D,它使用非常旧的 Mono 版本,而后者又使用了非常非最佳的 GC 实现。每个额外的内存分配都很重要:(
P.P.S 我正在构建自己的基于 C# 的解释器,避免反射似乎几乎是不可能的。
【问题讨论】:
-
据我所知,不,
FieldInfo.SetValue()仅具有接受object newValue的重载,因此您传递的任何值类型都会被装箱。 -
使用反射的性能比装箱值的工作量要数量级。将值装箱非常快,与正常设置字段与使用反射之间的差异相比,几乎快得无法估量。这就像在您决定从纽约步行到洛杉矶而不是乘坐飞机时,询问是否有办法避免系鞋带。
-
嗯,这实际上与速度无关,而与可能的 GC 压力有关。我正在使用 Unity,它使用非常旧的 Mono 版本,而后者又使用了非常非最佳的 GC 实现。每个额外的分配都很重要:(
-
@pachanga 为避免装箱而尝试做的任何事情无疑都需要做的不仅仅是分配一个简单的变量,因此会增加 GC压力,而不是删除它。
-
您也许可以获取 setter 方法并将其转换为委托类型。然后正常调用该委托。
标签: c# reflection mono boxing