How to deserialize byte[] into generic object to be cast at method call

半世苍凉 提交于 2020-01-12 22:27:16

问题


I am working on an object encryption class. I have everything worked out but I want to be able to encrypt/decrypt any object type with one deserialize method. As of now the only thing holding me up is the deserialize method. I have the function returning type(object) in the hopes of returning a weak typed object. It works as long as I cast the type during the return value assignment, but If I deserialize into type 'object' the result is byte[].

This means that I have to write a deserialize method for every object(T) i want to operate on. What I want to do is pass Type(T) as a parameter to the deserialize method so I can deserialize into object(T), then return the typed object.

The problem is that using a typed parameter is apparently not allowed.
If I do obj = (type.GetType())br.Deserialize(ms); I get ; expected between '(object(T)) and br.'.

If I do obj = (br.Deserialize(ms) as type); I get The type of namespace "type" could not be found. (are you missing a using directive or an assembly reference?)

or I get a symbol can not be resolved error. Any help is appreciated. Full code is below.

        private byte[] serialize(object param)
    {
        byte[] encMsg = null;
        using (MemoryStream ms = new MemoryStream())
        {
            IFormatter br = new BinaryFormatter();
            br.Serialize(ms, param);
            encMsg = ms.ToArray();
        }

        return encMsg;
    }

    private object deserialize(byte[] param)
    {
        object obj = null;
        using (MemoryStream ms = new MemoryStream(param))
        {
            IFormatter br = new BinaryFormatter();
            obj = (br.Deserialize(ms) as myObject);
        }

        return obj;
    }

    private byte[] encrypt(byte[] param)
    {
        byte[] encMsg = null;
        using (Aes myAes = Aes.Create())
        {
            myAes.Padding = PaddingMode.ANSIX923;
            ICryptoTransform autoBot = myAes.CreateEncryptor(myAes.Key, myAes.IV);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, autoBot, CryptoStreamMode.Write))
                {
                    cs.Write(param, 0, (int)param.Length);
                }
                encMsg = ms.ToArray();
            }
        }
        return encMsg;
    }

    private byte[] decrypt(byte[] key, byte[] iv, byte[] param)
    {
        byte[] dcparam = null;
        using (Aes myAes = Aes.Create())
        {
            myAes.Padding = PaddingMode.ANSIX923;
            ICryptoTransform autoBot = myAes.CreateDecryptor(key, iv);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, autoBot, CryptoStreamMode.Write))
                {
                    cs.Write(param, 0, (int)param.Length);
                }
                dcparam = ms.ToArray();
            }
        }
        return dcparam;
    }

回答1:


The type you want to deserialize must be known at compile time.. So your method can be like:

private T Deserialize<T>(byte[] param)
{
    using (MemoryStream ms = new MemoryStream(param))
    {
        IFormatter br = new BinaryFormatter();
        return (T)br.Deserialize(ms);
    }
}

Now you can use it like

var myclass = Deserialize<MyClass>(buf);



回答2:


You need to simply utilize the type parameter of your class.

By trying to dynamically do a GetType or a cast, you're forcing a runtime evaluation, rather than using generics to create a compile-time referenced version.

The type parameter will compile a separate version of your class that is strongly typed for every parameter type T that is encounted by the compiler. So T is actually a placeholder for a strong reference.

obj = (br.Deserialize(ms) as T);


来源:https://stackoverflow.com/questions/33616621/how-to-deserialize-byte-into-generic-object-to-be-cast-at-method-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!