1

I am trying to Deserialize an object of type ListManager, but get a cast-error when trying. Im not sure what im doing wrong.

I serialize the object just fine by sending in

b.Serialize(fileStream, obj);

But when trying to deserialize the file back to an instance of a Listmanager I get cast error. The class is called "AnimalManager", and inherits from ListManager. This class contains a list of objects of type Animal. How come it wants to cast to animal, instead of Listmanager?

Object of type "AnimalManager" cannot be converted to object of type "Animal".

public static T OpenBin<T>(string filePath)
{
    FileStream fileStream = null;
    object obj;

    try
    {
        if (!File.Exists(filePath)) throw new FileNotFoundException("The file" + " was not found. ", filePath);

        fileStream = new FileStream(filePath, FileMode.Open);

        var b = new BinaryFormatter();

        obj = b.Deserialize(fileStream);
    }

    finally
    {
        fileStream?.Close();
    }

    return (T)obj;
}

[Serializable]
public class ListManager<T> : IListManager<T>
{
    private List<T> _mList;

    public ListManager()
    {
        _mList = new List<T>();
    }
}

[Serializable]
public class AnimalManager : ListManager<Animal>
{
}

Calling from Form1:

    private void button4_Click(object sender, EventArgs e)
    {
        var filepath = "test.bin";

        if (manager.BinaryDeSerialize(filepath))
        {
            MessageBox.Show("hhohjo");
        }
    }

Going to ListManager Instance(AnimalManager)

    public bool BinaryDeSerialize(string fileName)
    {
        var test = BinSerializerUtility.OpenBin<T>(fileName);

        return true;
    }
  • 2
    Can you show your calling of OpenBin as well as your serialization? – Max Weinzierl Mar 05 '17 at 12:51
  • 1
    Please read [ask] and provide a [mcve]. You're not deserializing into the same type as you used to serialize, or you're messing up the `T`s somewhere, but we can't analyze this from the code shown. – CodeCaster Mar 05 '17 at 12:58

1 Answers1

1

Your problem is how you are calling OpenBin. The generic you are passing to OpenBin is the type you are storing in ListManager. This means while your serialization may be working your deserialization is trying to cast the object to type T, which is Animal in the case of an AnimalManager. A solution is to make OpenBin non-generic but make it abstract and implement it inside AnimalManager so you can cast to AnimalManager and not T.

A better solution would be to provide a second generic variable to OpenBin. T is used by the elements of the container, so specify a different one for the static function like so:

public static E OpenBin<E>(string filePath)

You will have to specify the type when you call the function though, like so:

var test = BinSerializerUtility.OpenBin<AnimalManager>(fileName);

The problem with either of these approaches is that you must provide the type in the subclass.

This may provide a way to do it in the parent class using reflection:

How do I use reflection to call a generic method?

Community
  • 1
  • 1
Max Weinzierl
  • 1,231
  • 10
  • 13
  • But can you not have a generic deseralization method?I would like this to work on any type of "ListManager" that I might implement, not just AnimalManager? –  Mar 05 '17 at 13:34
  • Yea, a better idea would be to specify a second generic variable. I will update my answer – Max Weinzierl Mar 05 '17 at 13:48