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.

pachanga
  • 3,003
  • 4
  • 30
  • 45
  • 2
    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. – CodeCaster Dec 02 '15 at 15:23
  • its not possible. it doesnt seem useful either. if you are worried about performance try not to use reflection. – M.kazem Akhgary Dec 02 '15 at 15:28
  • 2
    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. – Servy Dec 02 '15 at 15:31
  • 2
    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 :( – pachanga Dec 02 '15 at 15:39
  • 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 ;) – M.kazem Akhgary Dec 02 '15 at 15:43
  • 2
    @pachanga 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. – Servy Dec 02 '15 at 15:46
  • @M.kazemAkhgary I'm building a C# interpreter, it's quite hard to avoid reflection usage for this task. – pachanga Dec 02 '15 at 16:03
  • @Servy well, variables of primitive types and structs don't produce any GC overhead – pachanga Dec 02 '15 at 16:05
  • 2
    @pachanga 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. – Servy Dec 02 '15 at 16:10
  • 1
    @Servy 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. – pachanga Dec 02 '15 at 16:17
  • 2
    Can you generate code dynamically? e.g. using `Reflection.Emit` or `Expression.Compile`? – CodesInChaos Dec 02 '15 at 16:39
  • @CodesInChaos I'm afraid no, there are certain reflection limitations under iOS. But thanks for the tips. – pachanga Dec 02 '15 at 17:54
  • 3
    You might be able to obtain the setter method and cast it to a delegate type. Then invoke that delegate normally. – CodesInChaos Dec 02 '15 at 18:33
  • That might work indeed, however setters will be required for all fields... – pachanga Dec 02 '15 at 20:25
  • 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. – Fattie Feb 17 '16 at 18:51
  • @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. – CodesInChaos Mar 22 '16 at 17:09
  • Does Unity3D support `__makeref` and `SetValueDirect`? – Jon Hanna Dec 29 '17 at 16:53
  • 2
    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. @pachanga 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 :( – user99999991 Nov 19 '20 at 19:15

1 Answers1

0

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

user99999991
  • 1,351
  • 3
  • 19
  • 43