views:

225

answers:

3

greetngs,

i have two classes:

[Serializable]
public class FireGridUnit
{
    public GridUnit FireGridLocation { get; set; }

}

[Serializable]
public class FireResult: FireGridUnit
{
    public bool Hit { get; set; }

    public bool ShipDestroyed { get; set; }

    public Ship.ValidShips DestroyedShipType {get; set;}

    public bool Win { get; set; }
}

as you see FireResult inherits FireGrdUnit.

in my code when i try to use them i get a runtime error:

Unable to cast object of type 'NietzscheBattleships.FireGridUnit' to type 'NietzscheBattleships.FireResult'.

is this because if i am serializing the class has to be independant ie not be inherited?

many thanks.

EDIT:

it happens here:

                    XmlSerializer ss;
                    StringWriter ww;

                    ss = new XmlSerializer(typeof(FireResult));
                    ww = new StringWriter();

                    ss.Serialize(ww, fireGridUnit);

                    MessageBox.Show("hello");

                    MessageBox.Show(ww.ToString());

it gives the error mentioned. if i take this out then it runs but obviously not doing what want it to do.

EDIT: i got it my mistake!

ss.Serialize(ww, fireGridUnit); should be ss.Serialize(ww, fireResult);

thanks.

+2  A: 

No, it has nothing to do with [Serializable]. The way polymorphism works is the other way around. You can only upcast ((ParentClass)childObject;) through the hierarchy and not downcast ((ChildClass)parentObject).

For instance:

//This is correct
FireResult result = new FireResult();
FireGridUnit unit = result;

//This just does not seem right
FireGridUnit unit = new FireGridUnit();
FireResult result = unit;

EDIT: Think of inheritance the following way. All FireResults are FireGridUnits, as such, you can convert FireResults to FireGridUnits. However, not all FireGridUnits are FireResult because, you could have a third class that inherits from FireGridUnit. As such, you can not convert ALL FireGridUnits to a FireResult.

Anzurio
could please explain with a bit more detail?
iEisenhower
thank you very much.
iEisenhower
+2  A: 

The [Serializable] does nothing here (XmlSerializer doesn't care); assuming the real problem is in the serialization API (not just the cast), then:

[XmlInclude(typeof(FireResult))]
public class FireGridUnit {...}

Then to use it, something like:

        XmlSerializer ser = new XmlSerializer(typeof(FireGridUnit));
        using (MemoryStream ms = new MemoryStream())
        {
            ser.Serialize(ms, new FireResult { Hit = true });
            ms.Position = 0;
            FireGridUnit fr = (FireGridUnit)ser.Deserialize(ms);
            Debug.WriteLine(fr is FireResult); // true
        }
Marc Gravell
Now how about that. Very interesting attribute, could have saved the day if I had read this two years ago :)
Sandor Drieënhuizen
+1  A: 

Nope, you can't down-cast a FireGridUnit to a FireResult. The other way around is fine. Either you serialized the wrong object or the cast you used on the return value of Deserialize() is wrong.

Hans Passant