Approximating Size of Serializable Class
I would like to know the approximate XML serialized size of a class instance, without actually serializing the instance. Certainly I can provide a property that explicitly sums together the size of all fields, along with padding for the XML tags that would be generated. However, (1) I'd like to know if there is already a tool that serves this purpose - perhaps an extension method and if not (2) I'd like to know how to make a loop that uses reflection to approximate the size.
Right now I'm making something like this:
private static readonly int averageTagSize = 20;
[NonSerialized]
public int EventSize
{
get
{
int size = 0;
FieldInfo[] fields = this.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
size += averageTagSize;
switch (field.FieldType){
case typeof(int):
size += 32;
break;
case typeof(string):
string temp = field.GetValue(this) as string;
开发者_运维问答 size += temp.Length;
break;
//...and so on
}
}
return 0;
}
}
The above code does not work, as the compiler will not let me switch on type info. Suggestions?
With XML serialization, there is no straightforward answer since the size all depends on what XML writer options are employed. For example, whether line endings and indentation are used makes a difference as to the final file output.
The approach you're taking could work for a rough estimate. However, you would also have to watch for any attributes defined on classes, properties, and fields that can control how exactly the XML is serialized.
As far as your switch
statement goes, the most straightforward replacement would be to use if..else if..else
blocks.
My previous post is erroneous. The answer I gave works in VB, but not in c#. One way to solve this problem would be to hardcode the type names like so:
switch (field.FieldType.Name)
{
case "Int32":
size += 32;
break;
case "String":
string temp = field.GetValue(this) as string;
size += temp.Length;
break;
}
Alternatively you could use an if statement to avoid the use of hard-coded strings:
foreach (FieldInfo field in fields)
{
size += averageTagSize;
if (field.FieldType.Name == typeof(int).Name)
{
size += 32;
}
else if (field.FieldType.Name == typeof(string).Name)
{
string temp = field.GetValue(this) as string;
size += temp.Length;
}
}
While the existing answers are correct about your approach yielding only a very rough estimate, I believe the answer to your immediate question would be to use the string name of the types. I do not have access to a c# compiler at my home, but I believe it would look something like this:
switch (field.FieldType.Name){
case typeof(int).ToString():
.....
I hope that helps!
精彩评论