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. :(

+3


source to share


4 answers


There is an overload for ChangeType that takes an IFormatProvider , so you can call:



System.Convert.ChangeType(string, someType, CultureInfo.InvariantCulture);

      

+4


source


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. :)

+2


source


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 .

0


source


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);

      

This test works

0


source







All Articles