CS.MEMB.NOT_SERIALIZABLE
オブジェクトのグラフ全体がシリアル化できるようにします。
この規則は、シリアル化できるクラス内で、シリアル化できないすべてのメンバーフィールドを指摘します。NonSerializedAttribute でマークされたフィールドは除外されます。ときには規則が、自分の制御下にない型を "Serializable" としてマークする必要があることを指摘する場合もあります。たとえば、シリアル化可能としてマークされていないシステム型を使用している場合があります。この場合、このメンバーを "NonSerializable" としてマークするように修正を行う必要があり、逆シリアル化コンテキストで使用される前に、メンバーを適切に初期化する必要があります。
脆弱性とリスク
上記の規則に従わないクラスのオブジェクトをシリアル化すると、例外が発生する場合があります。
軽減と防止
クラスがカスタマイズされていない方法でシリアル化できる (SerializableAttribute でマークされ、ISerializable 属性を実装していない) 場合、そのすべてのフィールドは、シリアル化できるか、NonSerializableAttribute でマークされている必要があります。
注意: クラスが SerializableAttribute でマークされ、ISerializable を実装している場合、シリアル化はカスタマイズされ、この規則は適用されず、.TEST はこの規則の違反を示さないようになります。
脆弱コード例
コピー
public class Foo
{
}
public class Bar
{
}
[Serializable]
public class MyClass
{
private Foo _foo; // violation, class Foo is not
// serializable and field _foo is not
// skipped
// by NonSerializableAttribute
private Bar _bar; // violation, class Bar is not
// serializable and field _bar is not
// skipped
// by NonSerializableAttribute
private static void Serialize(MyClass obj)
{
Stream stream = File.Open("foo.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj); // an exception occurs
}
}
修正コード例 1
コピー
// There are two ways of fixing the above violations
// Fix #1
namespace Repair1
{
[Serializable]
public class Foo
{
}
public class Bar
{
}
[Serializable]
public class MyClass
{
private Foo _foo; // fix, Foo is serializable
[NonSerialized]
private Bar _bar; // fix, _bar is not serialized
private static void MySerializeMethod(MyClass obj)
{
Stream stream = File.Open("foo.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj); // no exception,
// all members are
// serializable
}
}
}
修正コード例 2
コピー
// Fix #2
namespace Repair2
{
public class Foo
{
}
public class Bar
{
}
[Serializable]
public class MyClass : ISerializable
{
private Foo _foo;
private Bar _bar;
private static void MySerializeMethod(MyClass obj)
{
Stream stream = File.Open("foo.dat", FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj); // no exception, all
// members are serializable
}
public void GetObjectData(
SerializationInfo info,
StreamingContext context)
{
/*
...
*/
}
}