Practical uses of TypedReference
Asked Answered
C

2

28

Are there any practical uses of the TypedReference struct that you would actually use in real code?

EDIT: The .Net framework uses them in overloads of Console.WriteLine and String.Concat which build an array from an __arglist parameter and pass it to the normal params overload. Why do these overloads exist?

Coeliac answered 10/11, 2009 at 21:36 Comment(3)
Why is this not constructive? :oFirebrand
Also see #4765073Firebrand
You can also use it to pass stack location / variable reference "around" (e.g. to other thread or return it from method). It requires unsafe code and "copying" TypedReference as two IntPtr.Terraqueous
L
20

Are there any practical uses of the TypedReference struct that you would actually use in real code?

Yes. I'd use them if I needed interoperability with C-style variadic methods.

Why do these overloads exist?

They exist for interoperability with callers who like to use C-style variadic methods.

Lithophyte answered 10/11, 2009 at 23:40 Comment(1)
+1 for not slamming the C-style varidiac bits :) And here's to hope you'll have variadic templates (not generics) by 5.0.Facelifting
C
17

This appears to be a very old question, but I'd like to add one more use-case: when you have a struct and want to set its variable through reflection, you would always operate on the boxed value and never change the original. This is useless:

TestFields fields = new TestFields { MaxValue = 1234 };
FieldInfo info = typeof(TestFields).GetField("MaxValue");
info.SetValue(fields, 4096);

// result: fields.MaxValue is still 1234!!

This can be remedied with implied boxing, but then you loose type safety. Instead, you can fix this with a TypedParameter:

TestFields fields = new TestFields { MaxValue = 1234 };
FieldInfo info = fields.GetType().GetField("MaxValue");

TypedReference reference = __makeref(fields);
info.SetValueDirect(reference, 4096);

// result: fields.MaxValue is now indeed 4096!!
Cognoscenti answered 30/3, 2012 at 14:35 Comment(4)
I don't know if I would call this a Reflection specific issue. SetValue takes an object as input, so any value type will be boxed to match the signature of the method.Satyr
@BrianRasmussen: afaik, this reflection-specific behavior stems from Reflection predating generics, otherwise boxing would not be needed. On (pre-)boxed value types and references this problem does not arise.Cognoscenti
My point was just that any method that takes object as input (which the first overload of SetValue in your example does) will force values to be boxed. That's how the unified type system handles values. That is not specific to Reflection.Satyr
Yes, and then the system introduced ref to work with value references, but SetXXX do not have ref-overloads. Indeed, the system is designed this way, isn't that the sole reason they added SetValueDirect and hence had to introduce an object that is both a reference to a value and an object?Cognoscenti

© 2022 - 2024 — McMap. All rights reserved.