Equals() private method

private Equals ( RuntimeTypeHandle handle ) : bool
handle RuntimeTypeHandle
return bool
Beispiel #1
0
 internal static RuntimeMethodInfo AssignAssociates(int tkMethod, RuntimeTypeHandle declaredTypeHandle, RuntimeTypeHandle reflectedTypeHandle)
 {
     if (MetadataToken.IsNullToken(tkMethod))
     {
         return null;
     }
     bool flag = !declaredTypeHandle.Equals(reflectedTypeHandle);
     RuntimeMethodHandle methodHandle = declaredTypeHandle.GetModuleHandle().ResolveMethodHandle(tkMethod, declaredTypeHandle.GetInstantiation(), new RuntimeTypeHandle[0]);
     MethodAttributes attributes = methodHandle.GetAttributes();
     bool flag2 = (attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
     bool flag3 = (attributes & MethodAttributes.Virtual) != MethodAttributes.PrivateScope;
     if (flag)
     {
         if (flag2)
         {
             return null;
         }
         if (flag3 && ((declaredTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.AnsiClass))
         {
             int slot = methodHandle.GetSlot();
             methodHandle = reflectedTypeHandle.GetMethodAt(slot);
         }
     }
     MethodAttributes attributes2 = attributes & MethodAttributes.MemberAccessMask;
     RuntimeMethodInfo methodBase = RuntimeType.GetMethodBase(reflectedTypeHandle, methodHandle) as RuntimeMethodInfo;
     if (methodBase == null)
     {
         methodBase = reflectedTypeHandle.GetRuntimeType().Module.ResolveMethod(tkMethod, null, null) as RuntimeMethodInfo;
     }
     return methodBase;
 }
Beispiel #2
0
 /// <summary>
 ///  Setter for RuntimeTypeHandle. Seperate from normal property as all uses should be done with great care.
 ///  Must not be set with partially constructed type handles
 /// </summary>
 public void SetRuntimeTypeHandleUnsafe(RuntimeTypeHandle runtimeTypeHandle)
 {
     Debug.Assert(!runtimeTypeHandle.IsNull());
     Debug.Assert(_runtimeTypeHandle.IsNull() || runtimeTypeHandle.Equals(_runtimeTypeHandle));
     Debug.Assert(runtimeTypeHandle.GetHashCode() == GetHashCode());
     _runtimeTypeHandle = runtimeTypeHandle;
 }
Beispiel #3
0
        internal unsafe static IntPtr ObjectToComInterfaceInternal(Object obj, RuntimeTypeHandle typeHnd)
        {
            if (obj == null)
                return default(IntPtr);

#if ENABLE_WINRT
            //
            // Try boxing if this is a WinRT object
            //
            if (typeHnd.Equals(InternalTypes.IInspectable))
            {
                object unboxed = McgMarshal.BoxIfBoxable(obj);

                //
                // Marshal ReferenceImpl<T> to WinRT as IInspectable
                //
                if (unboxed != null)
                {
                    obj = unboxed;
                }
                else
                {
                    //
                    // Anything that can be casted to object[] will be boxed as object[]
                    //
                    object[] objArray = obj as object[];
                    if (objArray != null)
                    {
                        unboxed = McgMarshal.BoxIfBoxable(obj, typeof(object[]).TypeHandle);
                        if (unboxed != null)
                            obj = unboxed;
                    }
                }
            }
#endif //ENABLE_WINRT

            //
            // If this is a RCW, and the RCW is not a base class (managed class deriving from RCW class), 
            // QI on the RCW
            //
            __ComObject comObject = obj as __ComObject;
            
            if (comObject != null && !comObject.ExtendsComObject)
            {
                IntPtr pComPtr = comObject.QueryInterface_NoAddRef_Internal(typeHnd,  /* cacheOnly= */ false, /* throwOnQueryInterfaceFailure= */ false);
                if (pComPtr == default(IntPtr))
                    return default(IntPtr);

                McgMarshal.ComAddRef(pComPtr);
                GC.KeepAlive(comObject); // make sure we don't collect the object before adding a refcount.

                return pComPtr;
            }

            //
            // Otherwise, go down the CCW code path
            //
            return ManagedObjectToComInterface(obj, typeHnd);
        }
Beispiel #4
0
        private static __ComObject CreateComObjectInternal(RuntimeTypeHandle classType, IntPtr pComItf)
        {
            Debug.Assert(!classType.IsNull());

            if (classType.Equals(McgModule.s_DependencyReductionTypeRemovedTypeHandle))
            {
                // We should filter out the strongly typed RCW in TryGetClassInfoFromName step
#if !RHTESTCL
                Environment.FailFast(McgTypeHelpers.GetDiagnosticMessageForMissingType(classType));
#else
                Environment.FailFast("We should never see strongly typed RCW discarded here");
#endif
            }
            
            //Note that this doesn't run the constructor in RH but probably do in your reflection based implementation. 
            //If this were a real RCW, you would actually 'new' the RCW which is wrong. Fortunately in CoreCLR we don't have
            //this scenario so we are OK, but we should figure out a way to fix this by having a runtime API.
            object newClass = InteropExtensions.RuntimeNewObject(classType);

            Debug.Assert(newClass is __ComObject);

            __ComObject newObj = InteropExtensions.UncheckedCast<__ComObject>(newClass);

            IntPtr pfnCtor = AddrOfIntrinsics.AddrOf<AddrOfIntrinsics.AddrOfAttachingCtor>(__ComObject.AttachingCtor);
            CalliIntrinsics.Call<int>(pfnCtor, newObj, pComItf, classType);

            return newObj;
        }
Beispiel #5
0
        /// <summary>
        /// Returns the existing RCW or create a new RCW from the COM interface pointer
        /// NOTE: This does unboxing unless CreateComObjectFlags.SkipTypeResolutionAndUnboxing is specified
        /// </summary>
        /// <param name="expectedContext">
        /// The current context of this thread. If it is passed and is not Default, we'll check whether the
        /// returned RCW from cache matches this expected context. If it is not a match (from a different 
        /// context, and is not free threaded), we'll go ahead ignoring the cached entry, and create a new
        /// RCW instead - which will always end up in the current context
        /// We'll skip the check if current == ContextCookie.Default. 
        /// </param>
        internal static object ComInterfaceToComObjectInternal(
            IntPtr pComItf,
            IntPtr pComIdentityIUnknown,
            RuntimeTypeHandle interfaceType,
            RuntimeTypeHandle classTypeInSignature,
            ContextCookie expectedContext,
            CreateComObjectFlags flags
            )
        {
            string className;
            object obj = ComInterfaceToComObjectInternal_NoCache(
                pComItf,
                pComIdentityIUnknown,
                interfaceType,
                classTypeInSignature,
                expectedContext,
                flags,
                out className
                );

            //
            // The assumption here is that if the classInfoInSignature is null and interfaceTypeInfo
            // is either IUnknow and IInspectable we need to try unboxing.
            //
            bool doUnboxingCheck = 
                (flags & CreateComObjectFlags.SkipTypeResolutionAndUnboxing) == 0 &&
                obj != null &&
                classTypeInSignature.IsNull() && 
                (interfaceType.Equals(InternalTypes.IUnknown) ||
                 interfaceType.IsIInspectable());

            if (doUnboxingCheck)
            {
                //
                // Try unboxing
                // Even though this might just be a IUnknown * from the signature, we still attempt to unbox
                // if it implements IInspectable
                //
                // @TODO - We might need to optimize this by pre-checking the names to see if they 
                // potentially represents a boxed type, but for now let's keep it simple and I also don't
                // want to replicate the knowledge here
                // @TODO2- We probably should skip the creating the COM object in the first place.
                //
                // NOTE: the RCW here could be a cached one (for a brief time if GC doesn't kick in. as there
                // is nothing to hold the RCW alive for IReference<T> RCWs), so this could save us a RCW
                // creation cost potentially. Desktop CLR doesn't do this. But we also paying for unnecessary
                // cache management cost, and it is difficult to say which way is better without proper
                // measuring
                //
                object unboxedObj = McgMarshal.UnboxIfBoxed(obj, className);
                if (unboxedObj != null)
                    return unboxedObj;
            }

            //
            // In order for variance to work, we save the incoming interface pointer as specified in the 
            // signature into the cache, so that we know this RCW does support this interface and variance 
            // can take advantage of that later
            // NOTE: In some cases, native might pass a WinRT object as a 'compatible' interface, for example,
            // pass IVector<IFoo> as IVector<Object> because they are 'compatible', but QI for IVector<object>
            // won't succeed. In this case, we'll just believe it implements IVector<Object> as in the 
            // signature while the underlying interface pointer is actually IVector<IFoo>
            //
            __ComObject comObject = obj as __ComObject;

            if (comObject != null)
            {
                McgMarshal.ComAddRef(pComItf);

                try
                {
                    comObject.InsertIntoCache(interfaceType, ContextCookie.Current, ref pComItf, true);
                }
                finally
                {
                    //
                    // Only release when a exception is thrown or we didn't 'swallow' the ref count by
                    // inserting it into the cache
                    //
                    McgMarshal.ComSafeRelease(pComItf);
                }
            }

            return obj;
        }
Beispiel #6
0
 internal static unsafe void AssignAssociates(AssociateRecord* associates, int cAssociates, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeHandle reflectedTypeHandle, out RuntimeMethodInfo addOn, out RuntimeMethodInfo removeOn, out RuntimeMethodInfo fireOn, out RuntimeMethodInfo getter, out RuntimeMethodInfo setter, out MethodInfo[] other, out bool composedOfAllPrivateMethods, out BindingFlags bindingFlags)
 {
     RuntimeMethodInfo info2;
     RuntimeMethodInfo info3;
     RuntimeMethodInfo info4;
     setter = (RuntimeMethodInfo) (info2 = null);
     getter = info3 = info2;
     fireOn = info4 = info3;
     addOn = removeOn = info4;
     other = null;
     Attributes attributes = Attributes.ComposedOfNoStaticMembers | Attributes.ComposedOfNoPublicMembers | Attributes.ComposedOfAllPrivateMethods | Attributes.ComposedOfAllVirtualMethods;
     while (reflectedTypeHandle.IsGenericVariable())
     {
         reflectedTypeHandle = reflectedTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal();
     }
     bool isInherited = !declaringTypeHandle.Equals(reflectedTypeHandle);
     ArrayList list = new ArrayList();
     for (int i = 0; i < cAssociates; i++)
     {
         RuntimeMethodInfo info = AssignAssociates(associates[i].MethodDefToken, declaringTypeHandle, reflectedTypeHandle);
         if (info != null)
         {
             MethodAttributes attributes2 = info.Attributes;
             bool flag2 = (attributes2 & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
             bool flag3 = (attributes2 & MethodAttributes.Virtual) != MethodAttributes.PrivateScope;
             MethodAttributes attributes3 = attributes2 & MethodAttributes.MemberAccessMask;
             bool flag4 = attributes3 == MethodAttributes.Public;
             bool flag5 = (attributes2 & MethodAttributes.Static) != MethodAttributes.PrivateScope;
             if (flag4)
             {
                 attributes &= ~Attributes.ComposedOfNoPublicMembers;
                 attributes &= ~Attributes.ComposedOfAllPrivateMethods;
             }
             else if (!flag2)
             {
                 attributes &= ~Attributes.ComposedOfAllPrivateMethods;
             }
             if (flag5)
             {
                 attributes &= ~Attributes.ComposedOfNoStaticMembers;
             }
             if (!flag3)
             {
                 attributes &= ~Attributes.ComposedOfAllVirtualMethods;
             }
             if (associates[i].Semantics == MethodSemanticsAttributes.Setter)
             {
                 setter = info;
             }
             else if (associates[i].Semantics == MethodSemanticsAttributes.Getter)
             {
                 getter = info;
             }
             else if (associates[i].Semantics == MethodSemanticsAttributes.Fire)
             {
                 fireOn = info;
             }
             else if (associates[i].Semantics == MethodSemanticsAttributes.AddOn)
             {
                 addOn = info;
             }
             else if (associates[i].Semantics == MethodSemanticsAttributes.RemoveOn)
             {
                 removeOn = info;
             }
             else
             {
                 list.Add(info);
             }
         }
     }
     bool isPublic = (attributes & Attributes.ComposedOfNoPublicMembers) == 0;
     bool isStatic = (attributes & Attributes.ComposedOfNoStaticMembers) == 0;
     bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
     composedOfAllPrivateMethods = (attributes & Attributes.ComposedOfAllPrivateMethods) != 0;
     other = (MethodInfo[]) list.ToArray(typeof(MethodInfo));
 }
        private bool FindMatchingInterfaceSlot(IntPtr moduleHandle, NativeReader nativeLayoutReader, ref NativeParser entryParser, ref ExternalReferencesTable extRefs, ref RuntimeTypeHandle declaringType, ref MethodNameAndSignature methodNameAndSignature, RuntimeTypeHandle openTargetTypeHandle, RuntimeTypeHandle[] targetTypeInstantiation, bool variantDispatch)
        {
            uint numTargetImplementations = entryParser.GetUnsigned();

            for (uint j = 0; j < numTargetImplementations; j++)
            {
                uint nameAndSigToken = extRefs.GetRvaFromIndex(entryParser.GetUnsigned());
                MethodNameAndSignature targetMethodNameAndSignature = GetMethodNameAndSignatureFromNativeReader(nativeLayoutReader, nameAndSigToken);
                RuntimeTypeHandle targetTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

#if REFLECTION_EXECUTION_TRACE
                ReflectionExecutionLogger.WriteLine("    Searching for GVM implementation on targe type = " + GetTypeNameDebug(targetTypeHandle));
#endif

                uint numIfaceImpls = entryParser.GetUnsigned();

                for (uint k = 0; k < numIfaceImpls; k++)
                {
                    RuntimeTypeHandle implementingTypeHandle = extRefs.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());

                    uint numIfaceSigs = entryParser.GetUnsigned();

                    if (!openTargetTypeHandle.Equals(implementingTypeHandle))
                    {
                        // Skip over signatures data
                        for (uint l = 0; l < numIfaceSigs; l++)
                            entryParser.GetUnsigned();

                        continue;
                    }

                    for (uint l = 0; l < numIfaceSigs; l++)
                    {
                        RuntimeTypeHandle currentIfaceTypeHandle = default(RuntimeTypeHandle);

                        NativeParser ifaceSigParser = new NativeParser(nativeLayoutReader, extRefs.GetRvaFromIndex(entryParser.GetUnsigned()));
                        IntPtr currentIfaceSigPtr = ifaceSigParser.Reader.OffsetToAddress(ifaceSigParser.Offset);

                        if (TypeLoaderEnvironment.Instance.GetTypeFromSignatureAndContext(currentIfaceSigPtr, targetTypeInstantiation, null, out currentIfaceTypeHandle, out currentIfaceSigPtr))
                        {
                            Debug.Assert(!currentIfaceTypeHandle.IsNull());

                            if ((!variantDispatch && declaringType.Equals(currentIfaceTypeHandle)) ||
                                (variantDispatch && RuntimeAugments.IsAssignableFrom(declaringType, currentIfaceTypeHandle)))
                            {
#if REFLECTION_EXECUTION_TRACE
                                ReflectionExecutionLogger.WriteLine("    " + (declaringType.Equals(currentIfaceTypeHandle) ? "Exact" : "Variant-compatible") + " match found on this target type!");
#endif
                                // We found the GVM slot target for the input interface GVM call, so let's update the interface GVM slot and return success to the caller
                                declaringType = targetTypeHandle;
                                methodNameAndSignature = targetMethodNameAndSignature;
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }
Beispiel #8
0
        public override bool HasTarget => _type == null;    // target is a type name

        internal CallStaticMethodBinder(RuntimeTypeHandle type, string name, RuntimeTypeHandle classContext, RuntimeTypeHandle returnType, int genericParams)
            : base(returnType, genericParams)
        {
            _type = type.Equals(default(RuntimeTypeHandle)) ? null : Type.GetTypeFromHandle(type);
            _name = name;
            _classCtx = classContext.Equals(default(RuntimeTypeHandle)) ? null : Type.GetTypeFromHandle(classContext);
        }
            public static unsafe IntPtr Get(RuntimeTypeHandle constraintType, RuntimeMethodHandle constrainedMethod)
            {
                lock (s_genericConstrainedCallDescs)
                {
                    // Get list of constrained call descs associated with a given type
                    LowLevelList<IntPtr> associatedCallDescs;
                    if (!s_genericConstrainedCallDescs.TryGetValue(constraintType, out associatedCallDescs))
                    {
                        associatedCallDescs = new LowLevelList<IntPtr>();
                        s_genericConstrainedCallDescs.Add(constraintType, associatedCallDescs);
                    }

                    // Perform linear scan of associated call descs to see if one matches
                    for (int i = 0; i < associatedCallDescs.Count; i++)
                    {
                        GenericConstrainedCallDesc* callDesc = (GenericConstrainedCallDesc*)associatedCallDescs[i];

                        Debug.Assert(constraintType.Equals(callDesc->_constraintType));

                        if (callDesc->_constrainedMethod != constrainedMethod)
                        {
                            continue;
                        }

                        // Found matching entry.
                        return associatedCallDescs[i];
                    }

                    // Did not find match, allocate a new one and add it to the lookup list
                    IntPtr newCallDescPtr = MemoryHelpers.AllocateMemory(sizeof(GenericConstrainedCallDesc));
                    GenericConstrainedCallDesc* newCallDesc = (GenericConstrainedCallDesc*)newCallDescPtr;
                    newCallDesc->_exactTarget = IntPtr.Zero;
                    if (RuntimeAugments.IsValueType(constraintType))
                    {
                        newCallDesc->_lookupFunc = s_resolveCallOnValueTypeFuncPtr;
                    }
                    else
                    {
                        newCallDesc->_lookupFunc = s_resolveCallOnReferenceTypeFuncPtr;
                    }

                    newCallDesc->_constraintType = constraintType;
                    newCallDesc->_constrainedMethod = constrainedMethod;

                    associatedCallDescs.Add(newCallDescPtr);

                    return newCallDescPtr;
                }
            }
Beispiel #10
0
        internal int Lookup(RuntimeTypeHandle handle)
        {
            for (int slot = GetFirst(handle.GetHashCode()); slot >= 0; slot = GetNext(slot))
            {
                int index = GetIndex(slot);

                if (handle.Equals(m_getHandle(index)))
                {
                    return index;
                }
            }

            return -1;
        }
Beispiel #11
0
 public static bool IsOfType(this Object obj, RuntimeTypeHandle handle)
 {
     return handle.Equals(obj.GetType().TypeHandle);
 }
        void InternalSerializeWithSurrogate(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
        {
            RuntimeTypeHandle objTypeHandle = isDeclaredType ? declaredTypeHandle : Type.GetTypeHandle(obj);
            object oldObj = obj;
            int objOldId = 0;
            Type objType = Type.GetTypeFromHandle(objTypeHandle);
            Type declaredType = GetSurrogatedType(Type.GetTypeFromHandle(declaredTypeHandle));

            if (TD.DCSerializeWithSurrogateStartIsEnabled())
            {
                TD.DCSerializeWithSurrogateStart(declaredType.FullName);
            }

            declaredTypeHandle = declaredType.TypeHandle;
            obj = DataContractSerializer.SurrogateToDataContractType(dataContractSurrogate, obj, declaredType, ref objType);
            objTypeHandle = objType.TypeHandle;
            if (oldObj != obj)
                objOldId = SerializedObjects.ReassignId(0, oldObj, obj);

            if (writeXsiType)
            {
                declaredType = Globals.TypeOfObject;
                SerializeWithXsiType(xmlWriter, obj, objTypeHandle, objType, -1, declaredType.TypeHandle, declaredType);
            }
            else if (declaredTypeHandle.Equals(objTypeHandle))
            {
                DataContract contract = GetDataContract(objTypeHandle, objType);
                SerializeWithoutXsiType(contract, xmlWriter, obj, declaredTypeHandle);
            }
            else
            {
                SerializeWithXsiType(xmlWriter, obj, objTypeHandle, objType, -1, declaredTypeHandle, declaredType);
            }
            if (oldObj != obj)
                SerializedObjects.ReassignId(objOldId, obj, oldObj);


            if (TD.DCSerializeWithSurrogateStopIsEnabled())
            {
                TD.DCSerializeWithSurrogateStop();
            }
        }
Beispiel #13
0
 public static IMapHandler Create(PropertyInfo propmeta)
 {
     System.RuntimeTypeHandle handle = propmeta.PropertyType.TypeHandle;
     if (handle.Equals(RTHString))
     {
         return(new MapHandler <T, String>(propmeta, (reader, index) => reader[index].ToString(), x => x));
     }
     else if (handle.Equals(RTHInt))
     {
         return(new MapHandler <T, Int32>(propmeta, (reader, index) => reader.GetInt32(index),
                                          x => { Int32 tmp; int.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHIntNullable))
     {
         return(new MapHandler <T, Nullable <Int32> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <Int32>) : reader.GetInt32(index),
                                                      x => { Int32 tmp; return int.TryParse(x, out tmp) ? tmp : default(Nullable <Int32>); }));
     }
     else if (handle.Equals(RTHDateTime))
     {
         return(new MapHandler <T, DateTime>(propmeta, (reader, index) => reader.GetDateTime(index),
                                             x => { DateTime tmp; DateTime.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHDateTimeNullable))
     {
         return(new MapHandler <T, Nullable <DateTime> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <DateTime>) : reader.GetDateTime(index),
                                                         x => { DateTime tmp; return DateTime.TryParse(x, out tmp) ? tmp : default(Nullable <DateTime>); }));
     }
     else if (handle.Equals(RTHGuid))
     {
         return(new MapHandler <T, Guid>(propmeta, (reader, index) => reader.GetGuid(index),
                                         x => { Guid tmp; Guid.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHGuidNullable))
     {
         return(new MapHandler <T, Nullable <Guid> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <Guid>) : reader.GetGuid(index),
                                                     x => { Guid tmp; return Guid.TryParse(x, out tmp) ? tmp : default(Nullable <Guid>); }));
     }
     else if (handle.Equals(RTHDouble))
     {
         return(new MapHandler <T, double>(propmeta, (reader, index) => reader.GetDouble(index),
                                           x => { double tmp; double.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHDoubleNullable))
     {
         return(new MapHandler <T, Nullable <double> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <double>) : reader.GetDouble(index),
                                                       x => { double tmp; return double.TryParse(x, out tmp) ? tmp : default(Nullable <double>); }));
     }
     else if (handle.Equals(RTHInt64))
     {
         return(new MapHandler <T, long>(propmeta, (reader, index) => reader.GetInt64(index),
                                         x => { long tmp; long.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHInt64Nullable))
     {
         return(new MapHandler <T, Nullable <long> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <long>) : reader.GetInt64(index),
                                                     x => { long tmp; return long.TryParse(x, out tmp) ? tmp : default(Nullable <long>); }));
     }
     else if (handle.Equals(RTHInt16))
     {
         return(new MapHandler <T, short>(propmeta, (reader, index) => reader.GetInt16(index),
                                          x => { short tmp; short.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHInt16Nullable))
     {
         return(new MapHandler <T, Nullable <short> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <short>) : reader.GetInt16(index),
                                                      x => { short tmp; return short.TryParse(x, out tmp) ? tmp : default(Nullable <short>); }));
     }
     else if (handle.Equals(RTHBool))
     {
         return(new MapHandler <T, bool>(propmeta, (reader, index) => reader.GetBoolean(index),
                                         x => { bool tmp; bool.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHBoolNullable))
     {
         return(new MapHandler <T, Nullable <bool> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <bool>) : reader.GetBoolean(index),
                                                     x => { bool tmp; return bool.TryParse(x, out tmp) ? tmp : default(Nullable <bool>); }));
     }
     else if (handle.Equals(RTHChar))
     {
         return(new MapHandler <T, char>(propmeta, (reader, index) => reader.GetChar(index),
                                         x => { char tmp; char.TryParse(x, out tmp); return tmp; }));
     }
     else if (handle.Equals(RTHCharNullable))
     {
         return(new MapHandler <T, Nullable <char> >(propmeta, (reader, index) => reader.IsDBNull(index) ? default(Nullable <char>) : reader.GetChar(index),
                                                     x => { char tmp; return char.TryParse(x, out tmp) ? tmp : default(Nullable <char>); }));
     }
     else if (handle.Equals(RTHBytes))
     {
         return(new MapHandler <T, byte[]>(propmeta, (reader, index) => reader.IsDBNull(index) ? default(byte[]) : (byte[])reader.GetValue(index),
                                           x => string.IsNullOrEmpty(x) ? default(byte[]) : System.Text.Encoding.UTF8.GetBytes(x)));
     }
     else if (propmeta.PropertyType.IsEnum)
     {
         return(new MapHandler <T>(propmeta));
     }
     else
     {
         return(new MapHandler(propmeta));
     }
 }
        internal static unsafe void AssignAssociates(
            AssociateRecord* associates,
            int cAssociates, 
            RuntimeTypeHandle declaringTypeHandle,
            RuntimeTypeHandle reflectedTypeHandle,
            out RuntimeMethodInfo addOn,
            out RuntimeMethodInfo removeOn,
            out RuntimeMethodInfo fireOn,
            out RuntimeMethodInfo getter,
            out RuntimeMethodInfo setter,
            out MethodInfo[] other,
            out bool composedOfAllPrivateMethods,
            out BindingFlags bindingFlags)
        {
            addOn = removeOn = fireOn = getter = setter = null;
            other = null;

            Attributes attributes = 
                Attributes.ComposedOfAllPrivateMethods |
                Attributes.ComposedOfAllVirtualMethods |
                Attributes.ComposedOfNoPublicMembers |
                Attributes.ComposedOfNoStaticMembers;

            while(reflectedTypeHandle.IsGenericVariable())
                reflectedTypeHandle = reflectedTypeHandle.GetRuntimeType().BaseType.GetTypeHandleInternal();

            bool isInherited = !declaringTypeHandle.Equals(reflectedTypeHandle);

            ArrayList otherList = new ArrayList();

            for (int i = 0; i < cAssociates; i++)
            {   
                #region Assign each associate
                RuntimeMethodInfo associateMethod = 
                    AssignAssociates(associates[i].MethodDefToken, declaringTypeHandle, reflectedTypeHandle);

                if (associateMethod == null)
                    continue;

                MethodAttributes methAttr = associateMethod.Attributes;
                bool isPrivate =(methAttr & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
                bool isVirtual =(methAttr & MethodAttributes.Virtual) != 0;

                MethodAttributes visibility = methAttr & MethodAttributes.MemberAccessMask;
                bool isPublic = visibility == MethodAttributes.Public;
                bool isNonProtectedInternal = visibility == MethodAttributes.Assembly;
                bool isStatic =(methAttr & MethodAttributes.Static) != 0;

                if (isPublic)
                {
                    attributes &= ~Attributes.ComposedOfNoPublicMembers;
                    attributes &= ~Attributes.ComposedOfAllPrivateMethods;
                }
                else if (!isPrivate)
                {
                    attributes &= ~Attributes.ComposedOfAllPrivateMethods;
                }

                if (isStatic)
                    attributes &= ~Attributes.ComposedOfNoStaticMembers;

                if (!isVirtual)
                    attributes &= ~Attributes.ComposedOfAllVirtualMethods;
                #endregion

                if (associates[i].Semantics == MethodSemanticsAttributes.Setter)
                    setter = associateMethod;
                else if (associates[i].Semantics == MethodSemanticsAttributes.Getter)
                    getter = associateMethod;
                else if (associates[i].Semantics == MethodSemanticsAttributes.Fire)
                    fireOn = associateMethod;
                else if (associates[i].Semantics == MethodSemanticsAttributes.AddOn)
                    addOn = associateMethod;
                else if (associates[i].Semantics == MethodSemanticsAttributes.RemoveOn)
                    removeOn = associateMethod;
                else
                    otherList.Add(associateMethod);
            }

            bool isPseudoPublic = (attributes & Attributes.ComposedOfNoPublicMembers) == 0;
            bool isPseudoStatic = (attributes & Attributes.ComposedOfNoStaticMembers) == 0;
            bindingFlags = RuntimeType.FilterPreCalculate(isPseudoPublic, isInherited, isPseudoStatic);

            composedOfAllPrivateMethods =(attributes & Attributes.ComposedOfAllPrivateMethods) != 0;

            other = (MethodInfo[])otherList.ToArray(typeof(MethodInfo));
        }
        internal static unsafe RuntimeMethodInfo AssignAssociates(
            int tkMethod,
            RuntimeTypeHandle declaredTypeHandle,
            RuntimeTypeHandle reflectedTypeHandle)
        {
            if (MetadataToken.IsNullToken(tkMethod))
                return null;

            ASSERT.PRECONDITION(!declaredTypeHandle.IsNullHandle());
            ASSERT.PRECONDITION(!reflectedTypeHandle.IsNullHandle());

            bool isInherited = !declaredTypeHandle.Equals(reflectedTypeHandle);

            RuntimeMethodHandle associateMethodHandle = declaredTypeHandle.GetModuleHandle().ResolveMethodHandle(tkMethod, declaredTypeHandle.GetInstantiation(), new RuntimeTypeHandle[0]);
            //RuntimeMethodHandle associateMethodHandle = declaredTypeHandle.GetMethodFromToken(tkMethod);
            ASSERT.CONSISTENCY_CHECK(!associateMethodHandle.IsNullHandle(), "Failed to resolve associateRecord methodDef token");

            MethodAttributes methAttr = associateMethodHandle.GetAttributes();
            bool isPrivate =(methAttr & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
            bool isVirtual =(methAttr & MethodAttributes.Virtual) != 0;

            if (isInherited)
            {
                // ECMA MethodSemantics: "All methods for a given Property or Event shall have the same accessibility 
                //(ie the MemberAccessMask subfield of their Flags row) and cannot be CompilerControlled  [CLS]"
                // Consequently, a property may be composed of public and private methods. If the declared type !=
                // the reflected type, the private methods should not be exposed. Note that this implies that the 
                // identity of a property includes it's reflected type.
                if (isPrivate)
                    return null;

                // Note this is the first time the property was encountered walking from the most derived class 
                // towards the base class. It would seem to follow that any associated methods would not
                // be overriden -- but this is not necessarily true. A more derived class may have overriden a
                // virtual method associated with a property in a base class without associating the override with 
                // the same or any property in the derived class. 
                if (isVirtual)
                {
                    bool declaringTypeIsClass = 
                        (declaredTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class;

                    ASSERT.CONSISTENCY_CHECK(LOGIC.BIJECTION(declaringTypeIsClass, 
                        (reflectedTypeHandle.GetAttributes() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class));

                    // It makes no sense to search for a virtual override of a method declared on an interface.
                    if (declaringTypeIsClass)
                    {
                        int slot = associateMethodHandle.GetSlot();

                        // Find the override visible from the reflected type
                        associateMethodHandle = reflectedTypeHandle.GetMethodAt(slot);
                    }
                }
            }

            MethodAttributes visibility = methAttr & MethodAttributes.MemberAccessMask;
            bool isPublic = visibility == MethodAttributes.Public;
            bool isNonProtectedInternal = visibility == MethodAttributes.Assembly;
            bool isStatic =(methAttr & MethodAttributes.Static) != 0;

            RuntimeMethodInfo associateMethod = 
                RuntimeType.GetMethodBase(reflectedTypeHandle, associateMethodHandle) as RuntimeMethodInfo;

            // suppose a property was mapped to a method not in the derivation hierarchy of the reflectedTypeHandle
            if (associateMethod == null)
                associateMethod = reflectedTypeHandle.GetRuntimeType().Module.ResolveMethod(tkMethod, null, null) as RuntimeMethodInfo;

            return associateMethod;
        }