CA2240: Implementujte správně ISerializable
Zboží | Hodnota |
---|---|
RuleId | CA2240 |
Kategorie | Microsoft.Usage |
Změna způsobující chybu | Nenarušující |
Příčina
Externě viditelný typ je možné přiřadit rozhraní System.Runtime.Serialization.ISerializable a jedna z následujících podmínek je pravdivá:
Typ dědí, ale nepřepíše metodu System.Runtime.Serialization.ISerializable.GetObjectData a typ deklaruje pole instance, která nejsou označena atributem System.NonSerializedAttribute .
Typ není zapečetěn a typ implementuje metodu GetObjectData , která není externě viditelná a přepisovatelná.
Popis pravidla
Pole instance deklarovaná v typu, který dědí System.Runtime.Serialization.ISerializable rozhraní, nejsou automaticky zahrnuta do procesu serializace. Chcete-li zahrnout pole, typ musí implementovat metodu GetObjectData a serializace konstruktor. Pokud by pole neměla být serializována, použijte NonSerializedAttribute atribut na pole explicitně indikovat rozhodnutí.
U typů, které nejsou zapečetěné, by měly být implementace GetObjectData metody externě viditelné. Proto lze metodu volat odvozenými typy a je přepsána.
Jak opravit porušení
Chcete-li opravit porušení tohoto pravidla, zviditelněte a přepsat metodu GetObjectData a ujistěte se, že všechna pole instance jsou zahrnuta do procesu serializace nebo explicitně označena atributem NonSerializedAttribute .
Kdy potlačit upozornění
Nepotlačujte upozornění na toto pravidlo.
Příklad 1
Následující příklad ukazuje dva serializovatelné typy, které porušují pravidlo.
using System;
using System.Security.Permissions;
using System.Runtime.Serialization;
namespace Samples1
{
// Violates this rule
[Serializable]
public class Book : ISerializable
{
private readonly string _Text;
public Book(string text)
{
if (text == null)
throw new ArgumentNullException("text");
_Text = text;
}
protected Book(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
_Text = info.GetString("Text");
}
public string Text
{
get { return _Text; }
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
info.AddValue("Text", _Text);
}
}
// Violates this rule
[Serializable]
public class LibraryBook : Book
{
private readonly DateTime _CheckedOut;
public LibraryBook(string text, DateTime checkedOut)
: base(text)
{
_CheckedOut = checkedOut;
}
public DateTime CheckedOut
{
get { return _CheckedOut; }
}
}
}
Příklad 2
Následující příklad opravuje dvě předchozí porušení tím, že poskytuje přepisovatelnou implementaci GetObjectData třídy Knihy a poskytnutím implementace GetObjectData
třídy Knihovny.
using System;
using System.Security.Permissions;
using System.Runtime.Serialization;
namespace Samples2
{
[Serializable]
public class Book : ISerializable
{
private readonly string _Title;
public Book(string title)
{
if (title == null)
throw new ArgumentNullException("title");
_Title = title;
}
protected Book(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
_Title = info.GetString("Title");
}
public string Title
{
get { return _Title; }
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Title", _Title);
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
GetObjectData(info, context);
}
}
[Serializable]
public class LibraryBook : Book
{
private readonly DateTime _CheckedOut;
public LibraryBook(string title, DateTime checkedOut)
: base(title)
{
_CheckedOut = checkedOut;
}
protected LibraryBook(SerializationInfo info, StreamingContext context)
: base(info, context)
{
_CheckedOut = info.GetDateTime("CheckedOut");
}
public DateTime CheckedOut
{
get { return _CheckedOut; }
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
protected override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("CheckedOut", _CheckedOut);
}
}
}
Související pravidla
- CA2236: Volejte metody třídy Base na typech ISerializable
- CA2229: Implementovat serializační konstruktory
- CA2238: Implementujte správně metody serializace
- CA2235: Označte všechna neserializovatelná pole
- CA2237: Označte typy ISerializable pomocí SerializableAttribute
- CA2239: Poskytujte metody deserializace pro nepovinné pole
- CA2120: Zabezpečte serializační konstruktory
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro