Is it possible to avoid boxing when setting C# struct/class fields using reflection?
Asked Answered
C

1

7

Say I have a primitive value which I need to assign to some field using reflection. I know for sure that field is of the same primitive value type.

Is it possible somehow to set this value without boxing?

void SetFloat(object o, string name, float val)
{
  var type = o.GetType();
  var fld = type.GetField(name);
  fld.SetValue(o, val /*boxing happens here*/);
}

P.S. It's not about latency really, it's about possible GC pressure. I'm using Unity3D which uses veeeery old Mono version which in its turn uses a very non-optimal GC implementation. Every extra memory allocation counts :(

P.P.S I'm building my own C# based interpreter, avoiding reflection seems almost impossible.

Communication answered 2/12, 2015 at 15:14 Comment(18)
As far as I can find, no, FieldInfo.SetValue() only has overloads accepting object newValue, so any value type you pass it will be boxed.Bowstring
its not possible. it doesnt seem useful either. if you are worried about performance try not to use reflection.Smarmy
The use of reflection at all is orders of magnitude more performance intensive than the effort spent boxing the value. Boxing a value is extremely fast, almost immeasurably fast in comparison to the difference between setting a field normally vs. using reflection. It's like asking if there's a way for you to avoid having to tie your shoes when you decide to walk from New York to Los Angeles instead of flying on a plane.Illyes
Well, it's not about speed really, it's about possible GC pressure. I'm using Unity which uses veeeery old Mono version which in its turn uses a very non-optimal GC implementation. Every extra allocation counts :(Communication
if its about possible GC pressure again dont use reflection. you are focusing to optimize 0.1% of your application while 99.9% remains unchanged ;)Smarmy
@Communication Anything you'd try to do to avoid boxing would unquestionably require doing more than allocating one simple variable, and would consequently add GC pressure, not remove it.Illyes
@M.kazemAkhgary I'm building a C# interpreter, it's quite hard to avoid reflection usage for this task.Communication
@Illyes well, variables of primitive types and structs don't produce any GC overheadCommunication
@Communication Again, anything that you'd try to do to avoid the boxing would unquestionably require doing even more work than what is spent boxing a single value. It wouldn't reduce the GC pressure, it'd increase it.Illyes
@Illyes sorry but I'm not convinced that doing more work is always going to increase GC pressure. I'm saying this since I've spent enormous amount of time optimizing my C# code in order to make it more GC friendly and in some cases it literally does much more than original version and yet it doesn't make any allocations.Communication
Can you generate code dynamically? e.g. using Reflection.Emit or Expression.Compile?Simard
@Simard I'm afraid no, there are certain reflection limitations under iOS. But thanks for the tips.Communication
You might be able to obtain the setter method and cast it to a delegate type. Then invoke that delegate normally.Simard
That might work indeed, however setters will be required for all fields...Communication
This question is a discussion. The concept under discussion is clearly not possible as agreed by all, and this site is simply not for discussions about philosophy of whether it would be a good idea to do something theoretically. @servy and others I suggest click Close to help clear some of the incredible clutter in the Unity3d tag. OP, don't hesitate to ask another clear question if you wish.Sexton
@JoeBlow The impossibility of this isn't clear to me. While I can't think of a way to accomplish it, the CLR has tricky low level corners which might allow this. I'd expect it to be possible, at least if you don't require verifiable code.Simard
Does Unity3D support __makeref and SetValueDirect?Digestible
It's upsetting to see this question not being answered and instead argued about "if its useful", since I too am looking into this exact same problem. Being impossible to do given the API is one thing, but the rest of the spam is not. @Communication did you ever resolve this? GC is incredibly sensitive and if you're doing this 1000x a second it hurts because the GC will invoke a clean up therefore stalling the frame. My work around has always been to manually write the code to set the values, but users want it to be automatic for them :(Ranunculaceous
R
0

It is possible with field.SetValueDirect but the downside is you cannot use IL2CPP because it does not support this.

Ranunculaceous answered 20/11, 2020 at 17:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.