gpt4 book ai didi

c# - ISerializable 和继承,正确使用,CA2236

转载 作者:太空宇宙 更新时间:2023-11-03 20:04:48 25 4
gpt4 key购买 nike

我对继承类中 ISerializable 的正确实现有疑问。

我有两个类,AbstractBaseClass 及其实现 BaseClass。在实现派生自 BaseClassFinalClass 之后,我收到了 CA 警告:

CA2236 Call base class methods on ISerializable types Method 'FinalClass.FinalClass(SerializationInfo, StreamingContext)' should be modified to call its base class implementation.

我不明白的是提取出来的info.GetString("FileName")info.GetString("Password")为什么还要调用基类足以创建 FinalClass 的实例吗?

问题:

1) 有人可以给我解释一下吗?

2) 如果我保持原样并取消警告,是否存在任何设计问题?

谢谢

简化的代码示例是:

public abstract class AbstractBaseClass : ISerializable
{
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue ...
//...
}

protected AbstractBaseClass() { }
protected AbstractBaseClass(SerializationInfo info, StreamingContext context)
{
if (info.GetInt32("Version") >= 1)
{
//...
}
}
}

public class BaseClass : AbstractBaseClass, ISerializable
{
public BaseClass() : base() { }

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue ...
}

protected BaseClass(SerializationInfo info, StreamingContext context)
: base(info, context)
{
if (info.GetInt32("Version") >= 1)
{
Connection = new MyConnection();
}
}
}

public class FinalClass : BaseClass
{
public string FileName { get; private set; }
public string Password { get; private set; }

public FinalClass(string fileName, string password)
: base()
{
FileName = fileName;
Password = password;
}

protected FinalClass(SerializationInfo info, StreamingContext context)
: this(info.GetString("FileName"), info.GetString("Password")) { }

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("FileName", FileName);
info.AddValue("Password", Password);
}
}

最佳答案

因为,一般来说,这是合理的建议。如果你改变了 base 实现中的某些东西,调用 base 将确保一切都将继续工作。

编译器不具备与您相同的知识。 知道没有必要调用 base,编译器不需要。编译器确实知道你正在做的事情并不违法,所以它只是发出警告,告诉你有一些代码可能需要你的注意(并且警告总是应该引起你的注意)。

如果这真的是您想要的,请取消警告,但我个人会调用基本构造函数,就像编译器建议的那样。

你现在所做的本身并没有错。这是完全有效的 C# 代码,但编译器决定发出警告,因为它“知道”(为简单起见)ISerializable 通常是如何与序列化构造函数结合实现的。

假设在下一次迭代中,BaseClass 添加了它自己的一些属性,即 Foo 属性,并假设我们希望对该属性进行(反)序列化。您可能会在 BaseClass(SerializationInfo, StreamingContext) 构造函数中实现必要的反序列化代码

public class BaseClass : AbstractBaseClass, ISerializable
{
public int Foo { get; set; }

protected BaseClass(SerializationInfo info, StreamingContext context)
: base(info, context)
{
// ...
Foo = info.GetInt32("Foo");
// ...
}
}

在您当前的设置中,当反序列化 FinalClass 时,BaseClass 的 Foo 属性不会被反序列化,因为您决定调用 this(string fileName, string password)构造函数,而不是 base(SerializationInfo, StreamingContext) 构造函数。 这就是此警告所针对的情况。该设置不是面向 future 的,将来对 AbstractBaseClassBaseClass 的任何添加也应该在构造函数中反序列化,但在您当前的实现中不会 被反序列化。

是的,您可以说当前的实现是设计错误,但我更可能将其称为设计的错误实现。

关于c# - ISerializable 和继承,正确使用,CA2236,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24407472/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com