2
votes

I'm having some trouble with binary serialization in C#... I should add that I'm a relative noob with C#, so please explain in simple terms :)

Anyway, I have this class (truncated for clarity):

[Serializable]
public class Player : Ship {

And Ship looks like this (again, truncated):

[Serializable]
public class Ship : TiledActor {
    public float MaxUserTurnPerSecond;
    public float RemainingShieldStrength;
    public float MaxShieldStrength;
    public float ShieldRechargeRate;
    public float ShieldRechargeDelay;
    public Color ShieldColor;
    public float ThrusterAccelerationScale;
    public Color RippleTrailColor;
    public float MinimumRippleSpeed;
    public float MaxEnergy;
    public float CurrentEnergy;
    public float EnergyRechargeRate;
    public float MaxSecondaryAmmoCapacity;
    public int CurrentSecondaryAmmoCount;
    public Weapon PrimaryWeapon;
    public Weapon SecondaryWeapon;
    protected ShieldActor ShieldTex;

    [NonSerialized]
    public MoXNA.ParticleMachines.PM_Explosion_Particle_Count ExplosionSize;
    [NonSerialized]
    protected MoXNA.ParticleMachines.MinSpeedRippleTrail rippleTrail;

    /* ... Truncated here */

So, as you can see, I wish to serialize the Player class. However, when I try this, I get this error:

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll

Additional information: Type 'MoXNA.ParticleMachines.MinSpeedRippleTrail' in Assembly 'SpaceshipInABox, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

The odd thing here is that I marked rippleTrail (which is the MinSpeedRippleTrail object) as [NonSerialized]... I don't want to serialize it (it's just a visual effect).

I used "Find all references" and that's the only MinSpeedRippleTrail object in the entire program, so what the hell?

Thanks.

2
Can you show the code where this error is thrown? Which data you are trying to write and what not. - Spidy
Are the types : Color, Weapon, ShieldActor serializable ? - Maciek
I don't see why this doesn't work, but you can give the following a try. Try adding Serializable to the MinSpeedRippleTrail class/struct anyhow, perhaps even though the NonSerialized attribute is applied, it still checks first whether it can be serialized? - Steven Jeuris
There's no decent explanation for this. Only a crummy one, your program is loading an old version of the assembly. Fuslogvw.exe and log all binds to double-check this. Also watch out for deserializing old data. - Hans Passant

2 Answers

4
votes

The usual problem here is an event. BinaryFormatter includes events, which many people don't expect. The event field must be marked, for example:

[field:NonSerialized]
public event EventHandler Foo;

It is painfully easy to get an event subscription that you didn't anticipate break the serializer (a capture class, perhaps).

However, I also encourage you:

  • don't use public fields; use properties
  • don't use BinaryFormatter - it bites most people eventually; and bites hard

If you want a binary serializer that works with XNA, consider protobuf-net; it is faster, has smaller output, adapts to change more gracefully ... and is free. Caveat: I wrote it.

0
votes

If you are using XML serialization you can use XmlIgnoreAttribute, otherwise change rippleTrail member to a method. for example: GetRippleTrail()