private static uint OffsetOfByDynamic(FieldInfo fieldInfo) { if (fieldOffsetCache == null) { lock (lockObject) { if (fieldOffsetCache == null) { fieldOffsetCache = new IdCache <uint>(); fieldOffsetCacheLock = new object(); } } } var fieldId = (long)fieldInfo.FieldHandle.Value; if (fieldOffsetCache.TryGetValue(fieldId, out uint offset)) { return(offset); } lock (fieldOffsetCacheLock) { if (fieldOffsetCache.TryGetValue(fieldId, out offset)) { return(offset); } GetAllFieldOffsetByDynamic(fieldInfo.DeclaringType); return(fieldOffsetCache[fieldId]); } }
/// <summary> /// 获取类型的静态内存地址位置。 /// </summary> /// <param name="type">类型信息</param> /// <returns>返回内存地址。</returns> public static IntPtr GetTypeStaticMemoryAddress(Type type) { if (StaticFieldAddressCache == null) { lock (typeof(TypeHelper)) { if (StaticFieldAddressCache == null) { StaticFieldAddressCache = new IdCache <IntPtr>(); StaticFieldAddressCacheLock = new object(); } } } var typeId = (long)GetTypeHandle(type); if (StaticFieldAddressCache.TryGetValue(typeId, out var value)) { return(value); } lock (StaticFieldAddressCacheLock) { if (StaticFieldAddressCache.TryGetValue(typeId, out value)) { return(value); } value = GetTypeStaticMemoryAddressByDynamic(type); StaticFieldAddressCache.Add(typeId, value); return(value); } }
public static bool IsEmptyValue(object value) { if (value == null) { return(true); } if (defaultValues == null) { lock (lockObject) { if (defaultValues == null) { defaultValues = new IdCache <object>(); } } } if (defaultValues.TryGetValue((long)Pointer.GetTypeHandle(value), out var default_value)) { return(RuntimeHelpers.Equals(value, default_value)); } lock (defaultValues) { var objectHandle = (long)Pointer.GetTypeHandle(value); if (!defaultValues.TryGetValue(objectHandle, out default_value)) { var type = value.GetType(); if (type.IsValueType) { default_value = Activator.CreateInstance(type); } else { default_value = null; } defaultValues.DirectAdd(objectHandle, default_value); } } return(RuntimeHelpers.Equals(value, default_value)); }
/// <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 SConvert() { Cache = new IdCache <ISConvert <TSource> >(); CacheLock = new object(); }
static DConvert() { Cache = new IdCache <IDConvert <TDestination> >(); CacheLock = new object(); }