static CloneHelper() { FuncMemberwiseClone = MethodHelper.CreateDelegate <Func <object, object> >( typeof(object).GetMethod(nameof(MemberwiseClone), BindingFlags.NonPublic | BindingFlags.Instance), false); }
/// <summary> /// 获取一个类型占用的内存大小。如果是 Class 则不包括 ObjectHandle 的大小。 /// </summary> /// <param name="type">类型信息</param> /// <returns>返回内存大小。</returns> public unsafe static uint SizeOf(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (type is TypeBuilder) { throw new ArgumentException("Unable get size of a TypeBuilder.", nameof(type)); } if (type.IsGenericTypeDefinition) { throw new ArgumentException("Unable get size of a generic definition type.", nameof(type)); } if (type.IsGenericTypeDefinition) { return(0); } switch (Type.GetTypeCode(type)) { case TypeCode.Boolean: return(sizeof(bool)); case TypeCode.Char: return(sizeof(char)); case TypeCode.SByte: return(sizeof(sbyte)); case TypeCode.Byte: return(sizeof(byte)); case TypeCode.Int16: return(sizeof(short)); case TypeCode.UInt16: return(sizeof(ushort)); case TypeCode.Int32: return(sizeof(int)); case TypeCode.UInt32: return(sizeof(uint)); case TypeCode.Int64: return(sizeof(long)); case TypeCode.UInt64: return(sizeof(ulong)); case TypeCode.Single: return(sizeof(float)); case TypeCode.Double: return(sizeof(double)); case TypeCode.Decimal: return(sizeof(decimal)); case TypeCode.DateTime: return((uint)sizeof(DateTime)); } if (type.IsPointer || type.IsInterface || type.IsByRef || typeof(object) == type || typeof(IntPtr) == type) { return((uint)IntPtr.Size); } if (typeSizeCache == null) { lock (lockObject) { if (typeSizeCache == null) { typeSizeCache = new IdCache <uint>(); typeSizeCacheLock = new object(); } var sizeOfHelperMethod = typeof(Marshal).GetMethod(MarshalSizeOfHelperName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static); if (sizeOfHelperMethod != null) { sizeOfHelper = MethodHelper.CreateDelegate <SizeOfHelperDelegate>(sizeOfHelperMethod, SignatureLevels.Cast); } pointerSizeOfMethod = typeof(Pointer).GetMethod(nameof(Pointer.SizeOf), Type.EmptyTypes); } } if (type.IsValueType) { if (sizeOfHelper != null) { return((uint)sizeOfHelper(type, false)); } try { return((uint)Marshal.SizeOf(type)); } catch (Exception) { } } var typeId = (long)type.TypeHandle.Value; if (typeSizeCache.TryGetValue(typeId, out uint size)) { return(size); } lock (typeSizeCacheLock) { if (typeSizeCache.TryGetValue(typeId, out size)) { return(size); } if (type.IsValueType) { size = (uint)pointerSizeOfMethod.MakeGenericMethod(type).Invoke(null, null); } else { var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (fields.Length == 0) { size = (uint)IntPtr.Size; } else { int right = fields.Length - 1; var maxOffset = OffsetOf(fields[right]); var maxOffsetFieldType = fields[right].FieldType; while (right > 0) { --right; var offset = OffsetOf(fields[right]); if (offset > maxOffset) { maxOffset = offset; maxOffsetFieldType = fields[right].FieldType; } } // = last field offset + last field size + type handle size; size = maxOffset + (maxOffsetFieldType.IsValueType ? SizeOf(maxOffsetFieldType) : (uint)IntPtr.Size) + ((uint)IntPtr.Size); } } typeSizeCache[typeId] = size; } return(size); }
static CloneHelper() { FuncMemberwiseClone = MethodHelper.CreateDelegate <Func <object, object> >( typeof(object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance), SignatureLevels.Cast); }
private static object AllocateByInternal(Type type) { if (!allocateIsInitialized) { lock (typeof(TypeHelper)) { if (!allocateIsInitialized) { allocateIsInitialized = true; var allocateMethod = typeof(RuntimeTypeHandle).GetMethod(AllocateMethodName, BindingFlags.NonPublic | BindingFlags.Static); if (allocateMethod != null) { allocate = MethodHelper.CreateDelegate <AllocateDelegate>(allocateMethod, SignatureLevels.Cast); } var stubHelpersType = Type.GetType(StubHelpersTypeName); if (stubHelpersType != null) { var allocateInternalMethod = stubHelpersType.GetMethod(AllocateInternalName, BindingFlags.Static | BindingFlags.NonPublic); if (allocateInternalMethod != null) { allocateInternal = MethodHelper.CreateDelegate <AllocateInternalDelegate>(allocateInternalMethod, SignatureLevels.Cast); } } var activationServicesType = Type.GetType(ActivationServicesTypeName); if (activationServicesType != null) { var allocateUninitializedClassInstanceMethod = activationServicesType.GetMethod(AllocateUninitializedClassInstanceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); if (allocateUninitializedClassInstanceMethod != null) { allocateUninitializedClassInstance = MethodHelper.CreateDelegate <AllocateUninitializedClassInstanceDelegate>(allocateUninitializedClassInstanceMethod, SignatureLevels.Cast); } } } } } if (allocate != null) { try { return(allocate(type)); } catch (Exception) { } } if (allocateInternal != null) { try { return(allocateInternal(type.TypeHandle.Value)); } catch (Exception) { } } if (allocateUninitializedClassInstance != null) { try { return(allocateUninitializedClassInstance(type)); } catch (Exception) { } } return(null); }