C# SerializationException 类型“未标记为可序列化” - 但它是
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11507819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SerializationException Type "is not marked as serializable" - But it is
提问by jp2code
In Windows Forms, .NET Framework 4.0, I am trying to Serialize an instance of a class I wrote.
在 Windows 窗体、.NET Framework 4.0 中,我试图序列化我编写的类的实例。
The class is marked as Serializable, but the form that uses the class (obviously) is not.
该类被标记为 Serializable,但使用该类的表单(显然)不是。
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?
我的类中的所有内容都标记为 Serializable,那么为什么我仍然收到 SerializationException?


(Click >> HERE <<to open image full-size in a new window)
(点击>>这里<<在新窗口中打开全尺寸图像)
Update:
更新:
Here is my BrazierCuttoffclass and related parts:
这是我的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
}
This is the BrazierPayobject that is used in the class above:
这是在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; }
}
I even marked this enumerated type as Serializable (though, it should not need it):
我什至将此枚举类型标记为 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
}
采纳答案by jp2code
Resolved
解决
I needed to set a NonSerializedAttributefor the EventHandler.
我需要NonSerializedAttribute为EventHandler设置一个。
The event delegate could not be serialized in the class (see Delegates and Serialization).
无法在类中序列化事件委托(请参阅委托和序列化)。
Marking the field as NonSerializedAttributewas as easy as it sounds.
标记该领域就像NonSerializedAttribute听起来一样简单。
From my code, I simply added this line:
从我的代码中,我只是添加了这一行:
[field:NonSerializedAttribute()]
public event EventHandler BrazierCuttoffChanged;
回答by burning_LEGION
mark BrazierMatrix2as [Serializable]
标记BrazierMatrix2为[Serializable]
回答by Zach La Lond
This is something you can run into with any JSON serialization, including Web API in MVC 4.
这是任何 JSON 序列化都会遇到的问题,包括 MVC 4 中的 Web API。
I found this post to be very helpful when I was getting a serialization except on a const int value. Any const value needs to be marked with the same attribute as in Nick Freeman's answer:
我发现这篇文章在我获得序列化时非常有帮助,除了 const int 值。任何 const 值都需要使用与 Nick Freeman 的回答中相同的属性进行标记:
[field: NonSerializedAttribute]
const int iCantBeSerialized = 1;
回答by Monga
[field:NonSerializedAttribute()]
public event EventHandler BrazierCuttoffChanged;
Had the same problem, the PropertyChanged EventHandler of my serializable NotifyObject base class was subscribed by some viewmodels which went into the serialization queue therefore. Adding the NonSerializedAddtribute to this EventHandler saved my day. :-)
有同样的问题,我的可序列化 NotifyObject 基类的 PropertyChanged EventHandler 被一些视图模型订阅,因此进入序列化队列。将 NonSerializedAddtribute 添加到这个 EventHandler 拯救了我的一天。:-)

