2

I have a question which has bugged me a lot. I use JSON.Net to serialize/deserialize objects. I use this code to invoke methods via their parameter types.

If I run the following code I get an object[] {int, int}

Then I serialize/deserialize with Json.Net and after this process it turns to object[] {long, long}

Now my question: How can I alter the following code to preserve the type along with the values?

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

    }




}
dangi12012
  • 23
  • 3
  • Could you please clarify (preferably with compilable code) what exactly do you mean " Object[2] Array of type {int, int}" - assuming this means `int[2]` it should work fine... – Alexei Levenkov Feb 01 '15 at 00:54

1 Answers1

0

You need to change ArgumentsOf into generics otherwise the return type is Array of System.Object which serializes into

"$type": "System.Object[], mscorlib",

However if you specify a particular type int it will serialize into:

"$type": "System.Int32[], mscorlib",

Something like this:

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

Then the whole your sample would look so:

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

}
SlavaGu
  • 817
  • 1
  • 8
  • 15
  • Thank you very much for your answer. But this is not complete. It should work with any Method Eg. Multiply(int, double). Do you have any idea how to accomplish this? Thanks in advance. – dangi12012 Feb 01 '15 at 14:36