Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
288 views
in Technique[技术] by (71.8m points)

c# - SerializationException Type "is not marked as serializable" - But it is

In Windows Forms, .NET Framework 4.0, I am trying to Serialize an instance of a class I wrote.

The class is marked as Serializable, but the form that uses the class (obviously) is not.

I do not want to Serialize an instance of the form. I want to Serialize the data I have in my class.

Everything in my class is marked as Serializable, so why am I still getting the SerializationException?

SerializationException.png

(Click >> HERE << to open image full-size in a new window)

Update:

Here is my BrazierCuttoff class and related parts:

[Serializable()]
public class BrazierCuttoff : IEquatable<BrazierCuttoff> {
  private int qty;
  private int[] joint, pass, shift;
  private float mult;
  private BrazierPay a, b, c, d, e;
  public event EventHandler BrazierCuttoffChanged;
  public const int MAXIMUMSMALLQUANTITY = 20;
  EnumeratedLevel[,] eLvArray;
  /// <summary>
  /// Gets or Sets the Brazier Matrix values
  /// </summary>
  /// <param name="passRatioIndex">0=100%,1=95,2=90,3=85,4=80,5=75,6=70,7=65</param>
  /// <param name="minJointIndex">0=900,1=1200,2=1400,3=1600,4=1800,5=2000,6=2100,=2200</param>
  /// <returns>Brazier Matrix value</returns>
  public EnumeratedLevel this[int passRatioIndex, int minJointIndex] {
    get { return eLvArray[passRatioIndex, minJointIndex]; }
    set { eLvArray[passRatioIndex, minJointIndex] = value; }
  }
  /// <summary>
  /// Initializes a new Form Values object using default values
  /// </summary>
  public BrazierCuttoff() {
    A = new BrazierPay(5.0f);
    B = new BrazierPay(4.0f);
    C = new BrazierPay(3.0f);
    D = new BrazierPay(2.0f);
    E = new BrazierPay(1.0f);
    NA = new BrazierPay(0.0f);
    ShiftMinimum = new int[] { 12, 12, 12 };
    PassRatio = new int[] { 100, 95, 90, 85, 80, 75, 70, 65 };
    JointMinimum = new int[] { 900, 1200, 1400, 1600, 1800, 2000, 2100, 2200 };
    eLvArray = new EnumeratedLevel[8, 8];
    EnumeratedLevel level = EnumeratedLevel.NA_Silver;
    for (int y = 0; y < 8; y++) {
      for (int x = 0; x < 8; x++) {
        switch (y) {
          case 0: level = (x < 2) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break;
          case 1: level = (x == 0) ? EnumeratedLevel.C_Green : (x < 3) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break;
          case 2: level = (x < 2) ? EnumeratedLevel.C_Green : (x < 5) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break;
          case 3: level = (x == 0) ? EnumeratedLevel.D_Yellow : (x < 4) ? EnumeratedLevel.C_Green : (x < 6) ? EnumeratedLevel.B_Blue : EnumeratedLevel.A_Violet; break;
          case 4: level = (x < 2) ? EnumeratedLevel.D_Yellow : (x < 5) ? EnumeratedLevel.C_Green : EnumeratedLevel.B_Blue; break;
          case 5: level = (x == 0) ? EnumeratedLevel.E_Orange : (x < 3) ? EnumeratedLevel.D_Yellow : (x < 6) ? EnumeratedLevel.C_Green : EnumeratedLevel.B_Blue; break;
          case 6: level = (x < 2) ? EnumeratedLevel.E_Orange : (x < 5) ? EnumeratedLevel.D_Yellow : EnumeratedLevel.C_Green; break;
          default: level = (x == 0) ? EnumeratedLevel.NA_Silver : (x < 5) ? EnumeratedLevel.E_Orange : EnumeratedLevel.D_Yellow; break;
        }
        eLvArray[x, y] = level;
      }
    }
  }

  private void broadcast() {
    if (BrazierCuttoffChanged != null) {
      BrazierCuttoffChanged(this, new EventArgs());
    }
  }
  /// <summary>
  /// Gets or Sets the A Pay Level data
  /// </summary>
  public BrazierPay A { get { return a; } set { if (a != value) { a = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the B Pay Level data
  /// </summary>
  public BrazierPay B { get { return b; } set { if (b != value) { b = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the C Pay Level data
  /// </summary>
  public BrazierPay C { get { return c; } set { if (c != value) { c = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the D Pay Level data
  /// </summary>
  public BrazierPay D { get { return d; } set { if (d != value) { d = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the E Pay Level data
  /// </summary>
  public BrazierPay E { get { return e; } set { if (e != value) { e = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the N/A Pay Level data
  /// </summary>
  public BrazierPay NA { get; private set; }

  public void Refresh() {
    const float delta = 0.01f;
    while (A.Dirty || B.Dirty || C.Dirty || D.Dirty || E.Dirty) {
      if (A.Dirty) {
        if (A.Value <= B.Value) B.Value = A.Value - delta;
        A.Dirty = false;
      } else if (B.Dirty) {
        if (B.Value <= C.Value) C.Value = B.Value - delta;
        if (A.Value <= B.Value) A.Value = B.Value + delta;
        B.Dirty = false;
      } else if (C.Dirty) {
        if (C.Value <= D.Value) D.Value = C.Value - delta;
        if (B.Value <= C.Value) B.Value = C.Value + delta;
        C.Dirty = false;
      } else if (D.Dirty) {
        if (D.Value <= E.Value) E.Value = D.Value - delta;
        if (C.Value <= D.Value) C.Value = D.Value + delta;
        D.Dirty = false;
      } else if (E.Dirty) {
        if (D.Value <= E.Value) D.Value = E.Value + delta;
        E.Dirty = false;
      }
    }
  }
  /// <summary>
  /// Gets the minimum Average Joints requirement
  /// </summary>
  public int AverageJoints { get { return JointMinimum[0]; } }
  /// <summary>
  /// Gets the minimum Chamber Pass Ratio requirement
  /// </summary>
  public int FirstTimePassRate { get { return PassRatio[PassRatio.Length - 1]; } }
  /// <summary>
  /// Gets or sets the Minimum Average Joints requirements (Range: 0 @ 900 to 7 @ 2200)
  /// </summary>
  public int[] JointMinimum { get { return joint; } set { if (joint != value) { joint = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the Chamber Pass Ratio levels (Range: 0 @ 100% to 7 @ 65%)
  /// </summary>
  public int[] PassRatio { get { return pass; } set { if (pass != value) { pass = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the Integral Array of minimum shifts required to qualify for a bonus
  /// </summary>
  public int[] ShiftMinimum { get { return shift; } set { if (shift != value) { shift = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the Small Workorder Multiplier (1 is default/disable)
  /// </summary>
  public float SmallWoMulti { get { return mult; } set { if (mult != value) { mult = value; broadcast(); } } }
  /// <summary>
  /// Gets or Sets the Small Workorder Quantity value (0 is disable)
  /// </summary>
  public int SmallWoQty { get { return qty; } set { if (qty != value) { qty = value; broadcast(); } } }

  #region IEquatable<BrazierCuttoff> Members

  public bool Equals(BrazierCuttoff other) {
    if (other != null) {
      if ((A == other.A) && (B == other.B) && (C == other.C) && (D == other.D) && (E == other.E) && (NA == other.NA)) {
        if ((ShiftMinimum == other.ShiftMinimum) && (PassRatio == other.PassRatio) && (JointMinimum == other.JointMinimum)) {
          return (eLvArray == other.eLvArray);
        }
      }
    }
    return false;
  }

  #endregion

}

This is the BrazierPay object that is used in the class above:

[Serializable()]
public class BrazierPay {
  float pay;
  public BrazierPay(float payLevel) {
    Dirty = false;
    pay = payLevel;
  }
  public float Value {
    get { return pay; }
    set {
      if (pay != value) {
        Dirty = true;
        pay = value;
      }
    }
  }
  public bool Dirty { get; set; }
  public string DollarValue { get { return string.Format("{0:C}", pay); } }
  public string Formatted { get { return string.Format("{0:F}", pay); } }
  public override string ToString() { return Formatted; }
}

I even marked this enumerated type as Serializable (though, it should not need it):

[Serializable()]
public enum EnumeratedLevel {
  NA_Silver = Clicker.NA_Silver, // Color.Silver
  E_Orange = Clicker.E_Orange, // Color.Orange
  D_Yellow = Clicker.D_Yellow, // Color.Yellow
  C_Green = Clicker.C_Green, // Color.Lime
  B_Blue = Clicker.B_Blue, // Color.DodgerBlue
  A_Violet = Clicker.A_Violet, // Color.Violet
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Resolved

I needed to set a NonSerializedAttribute for the EventHandler.

The event delegate could not be serialized in the class (see Delegates and Serialization).

Marking the field as NonSerializedAttribute was as easy as it sounds.

From my code, I simply added this line:

[field:NonSerializedAttribute()]
public event EventHandler BrazierCuttoffChanged;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...