In C #, what's the safest way to do the altogether primitive to string conversion for serialization?
I would like to generalize class / structure serialization in C #. For simplicity, let's assume class / struct can only be one level deep (no struct structures).
This is what I would like to write
System.Text.StringBuilder builder = new System.Text.StringBuilder();
System.Reflection.FieldInfo[] fields = obj.GetType().GetFields();
foreach (System.Reflection.FieldInfo info in fields) {
object fieldValue = info.GetValue(obj);
if (fieldValue != null) {
builder.Append(fieldValue.ToString());
}
...
}
Unfortunately, as far as I can tell, it won't work because it is ToString()
culture sensitive. In other words, for Single
it can output 12.345
or 12,345
depending on the culture settings.
Are there any other culture insensitive ToString
that I can call for primitive types?
Also, is there a non-standard generic string for the object function. I am currently using
object value = System.Convert.ChangeType(string, someType);
But it also seems to be culture sensitive. :(
source to share
There is an overload for ChangeType that takes an IFormatProvider , so you can call:
System.Convert.ChangeType(string, someType, CultureInfo.InvariantCulture);
source to share
Is there some other non-culture sensitive ToString that I can call on primitive types? Also, is there a non-standard generic string for the object function
IMHO, the simplest solution is to just format the string and pass the formatting. This way, you don't have to explicitly handle each individual value separately.
For example:
foreach (System.Reflection.FieldInfo info in fields) {
object fieldValue = info.GetValue(obj);
builder.AppendFormat(CultureInfo.InvariantCulture, "{0}", fieldValue);
...
}
This will work with any object that overrides ToString()
, although of course not all may necessarily implement IFormattable
. For these, whatever their normal ToString()
override will be used (which may still be culture dependent). However, C # primitives will work this way.
Note: as Stewart pointed out, the composite formatting system will handle the value null
automatically (returning an empty string), so you don't even need this check if you use the above.
In other words, the above does essentially the same as validation IFormattable
, using it if supported, and returning to otherwise ToString()
. It's just less code to write. :)
source to share
If you are talking about numbers and dates, you want CultureInfo.InvariantCulture
.
But it looks like you are talking about structured data and you want to deserialize that data as well. Therefore, you have to think about the format of this data in your string representation.
XML and JSON are popular choices for serialization formats. In modern .NET applications, XML is usually implemented with a classXDocument
or with DataContractSerializer
. JSON is best achieved using the JSON.NET library .
source to share
Based on @ Plutonix's comment, this is the answer I choose
System.Reflection.FieldInfo[] fields = obj.GetType().GetFields();
foreach (System.Reflection.FieldInfo info in fields) {
object fieldValue = info.GetValue(obj);
if (fieldValue != null) {
System.Type type = fieldValue.GetType();
string s = System.ComponentModel.TypeDescriptor.GetConverter(
type).ConvertToInvariantString(fieldValue);
...
}
}
Opposite
string s = System.ComponentModel.TypeDescriptor.GetConverter(
type).ConvertToInvariantString(fieldValue);
there is
object o = System.ComponentModel.TypeDescriptor.GetConverter(
type).ConvertFromInvariantString(s);
source to share