是的,你可能不会得到一个确切的数字。最好的办法是使用反射来迭代对象的层次结构并使用sizeof 计算所有值类型的大小。但这仍然不会告诉您确切的尺寸。
对于我提到的那个例子,你可以使用这样的代码
void Main()
{
var types = new List<object>{
(byte)1,
(short)1,
(int)1,
(long)1,
(double)1,
(decimal)1,
(float)1,
"omg afd obj amd",
"omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd omg afd obj amd ",
new Exception("Holy Maceral"),
};
foreach(var o in types)
{
Console.WriteLine("Size of {0} == {1}",o.GetType().Name,o.SizeOf());
}
}
public static class ExtensionMethods
{
public static int SizeOf(this object obj)
{
int size = 0;
if(obj == null)
return 0;
Type type = obj.GetType();
if(type.IsValueType)
{
return type.SizeOfType();
}
PropertyInfo[] info = type.GetProperties();
foreach(PropertyInfo property in info)
{
if(property.GetIndexParameters().Length > 0)
{
var ip = property.GetIndexParameters().First();
//Console.WriteLine(info);
var len = (int)info.FirstOrDefault(x=>x.Name == "Length" || x.Name == "Count").GetValue(obj);
for(var i = 0;i<len;i++)
{
size += property.GetValue(obj,new object[1]{i}).SizeOf();
}
}
else if(property.GetGetMethod().ReturnType.IsArray)
{
var arr = property.GetGetMethod().Invoke(obj,null);
foreach(var a in (Array)arr)
{
size+= a.SizeOf();
}
}
else if(property.PropertyType.IsValueType)
{
var val = property.GetValue(obj,null);
unsafe
{
size += property.PropertyType.SizeOfType();
}
}
else{
size += property.GetValue(obj,null).SizeOf();
}
}
return size;
}
public static int SizeOfType(this Type type)
{
if(type.IsValueType == false)
throw new ArgumentException("type must be value type");
return Marshal.SizeOf(type);
}
}
输出
Size of Byte == 1
Size of Int16 == 2
Size of Int32 == 4
Size of Int64 == 8
Size of Double == 8
Size of Decimal == 16
Size of Single == 4
Size of String == 19
Size of String == 116
Size of Exception == 36
它不是 100% 完美的,如果不进行一些调整,可能无法对每个对象都起作用,但它应该可以确定哪个对象最具攻击性。