引用类型是在堆上面分配的,与值类型不同的是,.NET没有办法直接计算得到它们所占用的大小。下面是一个解决方法。
using System;
using System.Reflection;
namespace Sample
{
public class Customer {
public int Id { get; set; }
public string CompanyName { get; set; }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(SizeOf
());
Console.Read();
}
public
static
int SizeOf
()
{
return SizeOf(
typeof(T));
}
public
unsafe
static
int SizeOf(Type targetType)
{
if (targetType ==
null)
return 0;
var result = 0;
foreach (var fld
in targetType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
switch (Type.GetTypeCode(fld.FieldType))
{
case TypeCode.Boolean: result +=
sizeof(
bool);
break;
case TypeCode.Byte: result +=
sizeof(
byte);
break;
case TypeCode.Char: result +=
sizeof(
char);
break;
case TypeCode.DateTime: result +=
sizeof(DateTime);
break;
case TypeCode.String:
case TypeCode.DBNull: result += IntPtr.Size;
break;
case TypeCode.Decimal: result +=
sizeof(
decimal);
break;
case TypeCode.Double: result +=
sizeof(
double);
break;
case TypeCode.Int16: result +=
sizeof(Int16);
break;
case TypeCode.Int32: result +=
sizeof(Int32);
break;
case TypeCode.Int64: result +=
sizeof(Int64);
break;
case TypeCode.SByte: result +=
sizeof(SByte);
break;
case TypeCode.Single: result +=
sizeof(
float);
break;
case TypeCode.UInt16: result +=
sizeof(UInt16);
break;
case TypeCode.UInt32: result +=
sizeof(UInt32);
break;
case TypeCode.UInt64: result +=
sizeof(UInt64);
break;
case TypeCode.Object:
if (fld.FieldType.Equals(
typeof(UIntPtr)))
{
result += UIntPtr.Size;
break;
}
if (fld.FieldType.Equals(
typeof(IntPtr)))
{
result += IntPtr.Size;
break;
}
if (fld.FieldType.IsValueType)
{
result += SizeOf(fld.FieldType);
break;
}
if (fld.FieldType.IsEnum)
{
result += SizeOf(Enum.GetUnderlyingType(fld.FieldType));
break;
}
result += IntPtr.Size;
break;
default:
continue;
}
return result + SizeOf(targetType.BaseType);
}
}
}
注意:选中下图中的“允许不安全代码”