3 // Copyright (c) Microsoft Corporation. All rights reserved.
8 // TypedReference is basically only ever seen on the call stack, and in param arrays.
9 // These are blob that must be dealt with by the compiler.
11 using System.Reflection;
12 using System.Runtime.CompilerServices;
13 using CultureInfo = System.Globalization.CultureInfo;
14 using FieldInfo = System.Reflection.FieldInfo;
15 using System.Security.Permissions;
16 using System.Runtime.Versioning;
17 using System.Diagnostics.Contracts;
20 [System.Runtime.InteropServices.ComVisible(true)]
21 [System.Runtime.Versioning.NonVersionable] // This only applies to field layout
22 public struct TypedReference
25 RuntimeTypeHandle type;
30 [System.Security.SecurityCritical] // auto-generated_required
32 public static TypedReference MakeTypedReference(Object target, FieldInfo[] flds) {
34 throw new ArgumentNullException("target");
36 throw new ArgumentNullException("flds");
37 Contract.EndContractBlock();
39 throw new ArgumentException(Environment.GetResourceString("Arg_ArrayZeroError"));
41 IntPtr[] fields = new IntPtr[flds.Length];
42 // For proper handling of Nullable<T> don't change GetType() to something like 'IsAssignableFrom'
43 // Currently we can't make a TypedReference to fields of Nullable<T>, which is fine.
44 RuntimeType targetType = (RuntimeType)target.GetType();
45 for (int i = 0; i < flds.Length; i++)
47 RuntimeFieldInfo field = flds[i] as RuntimeFieldInfo;
49 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"));
51 if (field.IsInitOnly || field.IsStatic)
52 throw new ArgumentException(Environment.GetResourceString("Argument_TypedReferenceInvalidField"));
54 if (targetType != field.GetDeclaringTypeInternal() && !targetType.IsSubclassOf(field.GetDeclaringTypeInternal()))
55 throw new MissingMemberException(Environment.GetResourceString("MissingMemberTypeRef"));
57 RuntimeType fieldType = (RuntimeType)field.FieldType;
58 if (fieldType.IsPrimitive)
59 throw new ArgumentException(Environment.GetResourceString("Arg_TypeRefPrimitve"));
61 if (i < (flds.Length - 1) && !fieldType.IsValueType)
62 throw new MissingMemberException(Environment.GetResourceString("MissingMemberNestErr"));
64 fields[i] = field.FieldHandle.Value;
65 targetType = fieldType;
69 return MakeTypedReferenceInternal (target, flds);
71 TypedReference result = new TypedReference ();
73 // reference to TypedReference is banned, so have to pass result as pointer
76 InternalMakeTypedReference(&result, target, fields, targetType);
82 [System.Security.SecurityCritical] // auto-generated
83 [ResourceExposure(ResourceScope.None)]
84 [MethodImplAttribute(MethodImplOptions.InternalCall)]
86 extern static TypedReference MakeTypedReferenceInternal (object target, FieldInfo[] fields);
88 // reference to TypedReference is banned, so have to pass result as pointer
89 private unsafe static extern void InternalMakeTypedReference(void* result, Object target, IntPtr[] flds, RuntimeType lastFieldType);
91 public override int GetHashCode()
93 if (Type == IntPtr.Zero)
96 return __reftype(this).GetHashCode();
99 public override bool Equals(Object o)
101 throw new NotSupportedException(Environment.GetResourceString("NotSupported_NYI"));
104 [System.Security.SecuritySafeCritical] // auto-generated
105 public unsafe static Object ToObject(TypedReference value)
107 return InternalToObject(&value);
110 [System.Security.SecurityCritical] // auto-generated
111 [ResourceExposure(ResourceScope.None)]
112 [MethodImplAttribute(MethodImplOptions.InternalCall)]
113 internal unsafe extern static Object InternalToObject(void * value);
119 return Value.IsNull() && Type.IsNull();
123 public static Type GetTargetType (TypedReference value)
125 return __reftype(value);
128 public static RuntimeTypeHandle TargetTypeToken (TypedReference value)
130 return __reftype(value).TypeHandle;
133 // This may cause the type to be changed.
134 [System.Security.SecuritySafeCritical] // auto-generated
135 [CLSCompliant(false)]
136 public unsafe static void SetTypedReference(TypedReference target, Object value)
139 throw new NotImplementedException ("SetTypedReference");
141 InternalSetTypedReference(&target, value);
145 [System.Security.SecurityCritical] // auto-generated
146 [ResourceExposure(ResourceScope.None)]
147 [MethodImplAttribute(MethodImplOptions.InternalCall)]
148 internal unsafe extern static void InternalSetTypedReference(void * target, Object value);