SerializationException类型“未标记为可序列化” - 但它确实如此

时间:2012-07-16 15:47:50

标签: c# winforms serialization

在Windows Forms,.NET Framework 4.0中,我正在尝试序列化我编写的类的实例。

该类被标记为Serializable,但使用该类的表单(显然)不是。

我不想序列化表单的实例。我想序列化我班上的数据。

我班上的所有内容都标记为Serializable,为什么我仍然会收到SerializationException?

SerializationException.png

(点击>> HERE <<在新窗口中打开图片的完整尺寸)

更新

这是我的BrazierCuttoff课程及相关部分:

[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

}

这是上面类中使用的BrazierPay对象:

[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; }
}

我甚至将此枚举类型标记为Serializable(但是,它不应该需要它):

[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
}

4 个答案:

答案 0 :(得分:21)

解决

我需要为 EventHandler 设置NonSerializedAttribute

无法在课程中序列化事件代理(请参阅Delegates and Serialization)。

将字段标记为NonSerializedAttribute就像听起来一样简单。

从我的代码中,我只是添加了这一行:

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

答案 1 :(得分:6)

这可以用于任何JSON序列化,包括MVC 4中的Web API。

我发现这篇文章在我获得序列化时非常有用,除了const int值。任何const值都需要用与Nick Freeman的答案相同的属性标记:

[field: NonSerializedAttribute]
const int iCantBeSerialized = 1;

答案 2 :(得分:2)

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

出现同样的问题,我的可序列化NotifyObject基类的PropertyChanged EventHandler被一些进入序列化队列的视图模型订阅。将NonSerializedAddtribute添加到此EventHandler节省了我的一天。 : - )

答案 3 :(得分:0)

BrazierMatrix2标记为[Serializable]