Json.Net 中的强类型 Object[]
Strongly typed Object[] in Json.Net
我有一个问题一直困扰着我。我使用 JSON.Net 到 serialize/deserialize 个对象。
我使用此代码通过参数类型调用方法。
如果我运行下面的代码我得到一个对象[] {int, int}
然后我 serialize/deserialize 和 Json.Net 并且在这个过程之后它变成 object[] {long, long}
现在我的问题是:如何更改以下代码以保留类型和值?
static class Program
{
static byte[] ObjectAsByteArray(object data)
{
string text = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings()
{
Formatting=Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return Encoding.UTF8.GetBytes(text);
}
static T ByteArrayAsObject<T>(byte[] data)
{
Object answer = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(T), new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return (T)answer;
}
static int Multiply(int a, int b)
{
return a * b;
}
static object[] ArgumentsOf(Expression<Action> expression)
{
MethodCallExpression outermostExpression = expression.Body as MethodCallExpression;
object[] Params = outermostExpression.Arguments.Cast<ConstantExpression>().Select(x => x.Value).ToArray();
return Params;
}
[STAThread]
static void Main()
{
object[] Arguments = ArgumentsOf(() => Multiply(5, 100));
byte[] ArgAsByte = ObjectAsByteArray(Arguments);
object[] DeserializedArguments = ByteArrayAsObject<object[]>(ArgAsByte);
}
}
您需要将 ArgumentsOf 更改为泛型,否则 return 类型是序列化为
的 System.Object 数组
"$type": "System.Object[], mscorlib",
但是,如果您指定特定类型的 int,它将序列化为:
"$type": "System.Int32[], mscorlib",
像这样:
static T[] ArgumentsOf<T>(Expression<Func<T>> expression)
{
MethodCallExpression outermostExpression = expression.Body as MethodCallExpression;
var Params = outermostExpression.Arguments.Cast<ConstantExpression>().Select(x => (T)x.Value).ToArray();
return Params;
}
然后你的整个样本看起来是这样的:
static class Program
{
static byte[] ObjectAsByteArray(object data)
{
string text = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings()
{
Formatting=Newtonsoft.Json.Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return Encoding.UTF8.GetBytes(text);
}
static T ByteArrayAsObject<T>(byte[] data)
{
var answer = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(T), new JsonSerializerSettings()
{
Formatting = Newtonsoft.Json.Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return (T)answer;
}
static int Multiply(int a, int b)
{
return a * b;
}
static T[] ArgumentsOf<T>(Expression<Func<T>> expression)
{
MethodCallExpression outermostExpression = expression.Body as MethodCallExpression;
var Params = outermostExpression.Arguments.Cast<ConstantExpression>().Select(x => (T)x.Value).ToArray();
return Params;
}
[STAThread]
static void Main()
{
var Arguments = ArgumentsOf(() => Multiply(5, 100));
byte[] ArgAsByte = ObjectAsByteArray(Arguments);
var DeserializedArguments = ByteArrayAsObject<int[]>(ArgAsByte);
}
}
我有一个问题一直困扰着我。我使用 JSON.Net 到 serialize/deserialize 个对象。 我使用此代码通过参数类型调用方法。
如果我运行下面的代码我得到一个对象[] {int, int}
然后我 serialize/deserialize 和 Json.Net 并且在这个过程之后它变成 object[] {long, long}
现在我的问题是:如何更改以下代码以保留类型和值?
static class Program
{
static byte[] ObjectAsByteArray(object data)
{
string text = JsonConvert.SerializeObject(data, Formatting.None, new JsonSerializerSettings()
{
Formatting=Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return Encoding.UTF8.GetBytes(text);
}
static T ByteArrayAsObject<T>(byte[] data)
{
Object answer = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(T), new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return (T)answer;
}
static int Multiply(int a, int b)
{
return a * b;
}
static object[] ArgumentsOf(Expression<Action> expression)
{
MethodCallExpression outermostExpression = expression.Body as MethodCallExpression;
object[] Params = outermostExpression.Arguments.Cast<ConstantExpression>().Select(x => x.Value).ToArray();
return Params;
}
[STAThread]
static void Main()
{
object[] Arguments = ArgumentsOf(() => Multiply(5, 100));
byte[] ArgAsByte = ObjectAsByteArray(Arguments);
object[] DeserializedArguments = ByteArrayAsObject<object[]>(ArgAsByte);
}
}
您需要将 ArgumentsOf 更改为泛型,否则 return 类型是序列化为
的 System.Object 数组"$type": "System.Object[], mscorlib",
但是,如果您指定特定类型的 int,它将序列化为:
"$type": "System.Int32[], mscorlib",
像这样:
static T[] ArgumentsOf<T>(Expression<Func<T>> expression)
{
MethodCallExpression outermostExpression = expression.Body as MethodCallExpression;
var Params = outermostExpression.Arguments.Cast<ConstantExpression>().Select(x => (T)x.Value).ToArray();
return Params;
}
然后你的整个样本看起来是这样的:
static class Program
{
static byte[] ObjectAsByteArray(object data)
{
string text = JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings()
{
Formatting=Newtonsoft.Json.Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return Encoding.UTF8.GetBytes(text);
}
static T ByteArrayAsObject<T>(byte[] data)
{
var answer = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(data), typeof(T), new JsonSerializerSettings()
{
Formatting = Newtonsoft.Json.Formatting.Indented,
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});
return (T)answer;
}
static int Multiply(int a, int b)
{
return a * b;
}
static T[] ArgumentsOf<T>(Expression<Func<T>> expression)
{
MethodCallExpression outermostExpression = expression.Body as MethodCallExpression;
var Params = outermostExpression.Arguments.Cast<ConstantExpression>().Select(x => (T)x.Value).ToArray();
return Params;
}
[STAThread]
static void Main()
{
var Arguments = ArgumentsOf(() => Multiply(5, 100));
byte[] ArgAsByte = ObjectAsByteArray(Arguments);
var DeserializedArguments = ByteArrayAsObject<int[]>(ArgAsByte);
}
}