为什么 TypedReference.MakeTypedReference 如此受限?

Ill*_*ack 5 c# clr interop typedreference

我终于明白了该方法的用法TypedReference.MakeTypedReference,但为什么参数如此有限?底层的 private可以做比限制字段数组有元素和字段类型为非原始的InternalMakeTypedReference(void* result, object target, IntPtr[] flds, RuntimeType lastFieldType)更多的事情。MakeTypedReference

我制作了一个示例使用代码,展示了它的全部可能性:

private static readonly MethodInfo InternalMakeTypedReferenceMethod = typeof(TypedReference).GetMethod("InternalMakeTypedReference", flags);
private static readonly Type InternalMakeTypedReferenceDelegateType = ReflectionTools.NewCustomDelegateType(InternalMakeTypedReferenceMethod.ReturnType, InternalMakeTypedReferenceMethod.GetParameters().Select(p => p.ParameterType).ToArray());
private static readonly Delegate InternalMakeTypedReference = Delegate.CreateDelegate(InternalMakeTypedReferenceDelegateType, InternalMakeTypedReferenceMethod);

public static void MakeTypedReference([Out]TypedReference* result, object target, params FieldInfo[] fields)
{
    IntPtr ptr = (IntPtr)result;
    IntPtr[] flds = new IntPtr[fields.Length];
    Type lastType = target.GetType();
    for(int i = 0; i < fields.Length; i++)
    {
        var field = fields[i];
        if(field.IsStatic)
        {
            throw new ArgumentException("Field cannot be static.", "fields");
        }
        flds[i] = field.FieldHandle.Value;
        lastType = field.FieldType;
    }
    InternalMakeTypedReference.DynamicInvoke(ptr, target, flds, lastType);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,实际调用它需要更多技巧,因为它不能被调用,MethodInfo并且一个参数是RuntimeType,因此必须动态生成委托类型(DynamicMethod也可以使用)。

现在这能做什么呢?它可以不受限制地访问任何对象的任何值的任何字段(类或结构类型,甚至原始类型)。此外,它还可以创建对装箱值类型的引用。

object a = 98;
TypedReference tr;
InteropTools.MakeTypedReference(&tr, a);
Console.WriteLine(__refvalue(tr, int)); //98
__refvalue(tr, int) = 1;
Console.WriteLine(a); //1
Run Code Online (Sandbox Code Playgroud)

那么,为什么开发人员看似毫无意义地决定禁止这种用法,而这显然是有用的呢?

Gle*_*den 3

责怪柏拉图和他该死的“类型论”......

这是任何(托管指针)引用本质上所固有的ref——包括新的 C# 7 ref localref return功能——正如您所观察到的,TypedReference,您可以使用它来读取写入目标。因为这不是重点吗?

现在,由于CTS无法排除其中任何一种可能性,因此强类型要求每个Type元素都ref受到类型层次结构中上层下层的约束。

更正式地说,Type被限制为多态协变和逆变的交集,否则它就符合条件。显然,这个交集的结果折叠成一个, 本身,从此以后它是不变的。Type