Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#中,什么';将原语转换为字符串进行序列化的安全方法是什么?_C#_String_Serialization_Deserialization - Fatal编程技术网

在C#中,什么';将原语转换为字符串进行序列化的安全方法是什么?

在C#中,什么';将原语转换为字符串进行序列化的安全方法是什么?,c#,string,serialization,deserialization,C#,String,Serialization,Deserialization,我想在C#中对类/结构进行一般序列化。为了简单起见,让我们假设类/结构只能有一层深度(没有结构的结构) 这是我想写的 System.Text.StringBuilder builder = new System.Text.StringBuilder(); System.Reflection.FieldInfo[] fields = obj.GetType().GetFields(); foreach (System.Reflection.FieldInfo info in fields) {

我想在C#中对类/结构进行一般序列化。为了简单起见,让我们假设类/结构只能有一层深度(没有结构的结构)

这是我想写的

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());
    }
    ...
}
不幸的是,据我所知,这不起作用,因为
ToString()
对区域性敏感。换句话说,对于
单个
,它可能会输出
12.345
12345
,具体取决于区域性设置

是否有其他非区域性敏感的
ToString
I可以调用基元类型

此外,还有一个非区域性敏感的通用字符串到对象函数。我目前正在使用

object value = System.Convert.ChangeType(string, someType);

但这显然也是文化敏感的(

对于ChangeType,有一个

System.Convert.ChangeType(string, someType, CultureInfo.InvariantCulture);
是否有其他非区域性敏感的字符串可以调用基本类型? 另外,是否存在非区域性敏感的通用字符串到对象函数

依我看,最简单的解决方案就是格式化字符串并传递一个格式化程序。这样你就不必显式地分别处理每个单独的值

例如:

foreach (System.Reflection.FieldInfo info in fields) {
    object fieldValue = info.GetValue(obj);
    builder.AppendFormat(CultureInfo.InvariantCulture, "{0}", fieldValue);
    ...
}
这将适用于覆盖
ToString()
的任何对象,当然并非所有对象都必须实现
IFormattable
。对于这些对象,无论其正常的
ToString()
覆盖做了什么,都将使用(可能仍然依赖于区域性)。不过,C原语都将以这种方式工作

注意:正如Stuart所指出的,复合格式系统将自动处理
null
值(返回空字符串),因此如果使用上述方法,您甚至不需要进行检查


换句话说,上面所做的工作本质上与检查
IFormattable
,如果支持的话使用它,或者使用
ToString()
。只需编写更少的代码。:

如果你谈论的是数字和日期,你需要
CultureInfo.InvariantCulture

但这听起来像是在谈论结构化数据,并且希望能够反序列化这些数据。因此,您应该考虑数据在其字符串表示中的格式


XML和JSON是序列化格式的常用选择。在现代.NET应用程序中,XML通常使用或实现。JSON的最佳实现方式是。

基于@puropoix comment,这是我选择的答案

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);
        ...
    }
}
相反的

string s = System.ComponentModel.TypeDescriptor.GetConverter(
               type).ConvertToInvariantString(fieldValue);


使用
TypeDescriptor.GetConverter
然后可以对类型的值使用
ConvertToInvariantString
非常简洁的解决方案,请注意,复合格式系统也通过以下方式处理空值—“如果要格式化的值为空,则返回空字符串(“”)”,这样代码就更少了!没错。我甚至没有想到那部分,但你是对的……我也可以去掉
null
检查。我想我会的另一个方向呢?对不起…我在问题中没有看到任何反序列化的请求。不幸的是,反序列化是完全不同的。您没有处理对象实例(即,可以提供多态解析实现的对象实例),您必须知道要反序列化所处理的类型。好的一面是,这意味着您可以始终将
CultureInfo.InvariantCulture
传递给相应的解析/反序列化方法,以反转上面的序列化操作。谢谢,但由于各种原因,我不能使用JSON.NET库或XML内容。@gman-发明全新的序列化格式比看起来更难,所以至少要考虑为什么现有的方法是这样做的:)如果你不喜欢文本格式的冗长——也许现有的二进制格式会是什么?请给我一些信任。我宁愿使用现有的解决方案。我看了看。它们不符合我的需要。例如为了处理多态类型,JSON.NET需要LINQ特性。但是我在Unity3D中使用的是C#.NET 2.0,它不支持LINQ。我的需求很小。我并不是在试图发明一个完整的100%序列化的解决方案。同时,如果有一种通用的C#方法来处理原语,我想知道它是什么。
object o = System.ComponentModel.TypeDescriptor.GetConverter(
               type).ConvertFromInvariantString(s);