Working SetTypedReference

162 views Asked by At

In the documentation I see TypedReference.SetTypedReference(target, value) is unsupported.

  1. Was this method designed to represent a type-independent equivalent of __refvalue(target, T) = value?

  2. Why was this method decided not to be supported? I wonder why an unimplemented method was chosen to be declared there in the first place.

  3. Is there this equivalent of __refvalue(target, T) = value, like there is TypedReference.ToObject(value) for __refvalue(value, T)?

Edit: For the third question, I've created the following code:

public static class TypedReferenceConvert
{   
    delegate void TypedReferenceSet(TypedReference tr, object value);
    static readonly Type thisType = typeof(TypedReferenceConvert);
    static readonly Type TypedReferenceSet_t = typeof(TypedReferenceSet);
    static readonly MethodInfo SetTypedReference_m = thisType.GetMethod("SetTypedReference", BindingFlags.NonPublic | BindingFlags.Static);
    static readonly Dictionary<Type,TypedReferenceSet> setcache = new Dictionary<Type,TypedReferenceSet>();

    public static void SetValue(this TypedReference target, object value)
    {
        TypedReferenceSet set;
        Type t = __reftype(target);
        if(!setcache.TryGetValue(t, out set))
        {
            lock(setcache)
                set = setcache[t] = (TypedReferenceSet)Delegate.CreateDelegate(TypedReferenceSet_t, SetTypedReference_m.MakeGenericMethod(t));
        }
        set(target, value);
    }

    private static void SetTypedReference<T>(TypedReference target, object value)
    {
        __refvalue(target, T) = (T)value;
    }

    public static object GetValue(this TypedReference target)
    {
        return TypedReference.ToObject(target);
    }
}

It's slower than the type-dependent __refvalue, but I don't think there is a better solution.

1

There are 1 answers

0
AudioBubble On BEST ANSWER

The documentation you link to has an option at the top to switch to the documentation for older versions of .NET Framework, including 1.1, which reads:

Return Value

This method assigns value to target. A change type of value converts it to the type of the TypedReference. The Convert.ChangeType method does the conversion.

This should answer your first question.

For your second question, it was originally implemented, but dropped in .NET 2.0. The documentation for .NET 2.0 does show it as implemented, but that's an error in the documentation (since fixed, as you've found).

As for why it was dropped, it's a bit of a guess, but I suspect that that can be combined with your third question: the only intended use case of TypedReference is for variable argument functions, and that does not require any modifications to the referenced values. The big thing that .NET 2.0 adds that .NET 1.1 didn't have is generics, and that gets rid of most of the unintended use cases as well (writing type-generic code that avoids boxing for value types), so I think there simply wasn't much point in implementing SetTypedReference. Now that you have generics, you could use them to do what you're after by calling a generic method instantiated with T.