29

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?

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    Why is this not constructive? :o – nawfal May 13 '13 at 17:07
  • 1
    Also see http://stackoverflow.com/questions/4764573/why-is-typedreference-behind-the-scenes-its-so-fast-and-safe-almost-magical – nawfal May 13 '13 at 17:24
  • 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. – Ondrej Petrzilka Nov 09 '16 at 23:38

2 Answers2

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.

konrad.kruczynski
  • 46,413
  • 6
  • 36
  • 47
Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 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. – rama-jka toti Nov 10 '09 at 23:47
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!!
Abel
  • 56,041
  • 24
  • 146
  • 247
  • 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. – Brian Rasmussen Mar 30 '12 at 14:49
  • @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. – Abel Mar 30 '12 at 15:07
  • 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. – Brian Rasmussen Mar 30 '12 at 15:10
  • 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? – Abel Mar 30 '12 at 15:22