【发布时间】:2021-08-10 14:31:26
【问题描述】:
我正在尝试对动物列表(猫或狗)进行二进制格式化。这在某种程度上很好。我在我的基类 Animal 中使用了 ISerialize 接口。两个派生类 dog 和 cat,但是它们都具有基类没有的 1 个额外属性。现在,基类动物的序列化和反序列化没有给我带来任何问题。当我尝试序列化和反序列化前面提到的派生类中的任何一个额外属性时,问题就开始了。我觉得这个问题很容易解决,但我正在监督一些事情。下面我将发布以下位置的代码:
- Animal 类中的 ISerialize 接口
- Dog 类中的 ISerialize 接口
- Cat 类中的 ISerialize 接口
- Administration 类中序列化器和反序列化器的实现(都绑定到表单中的两个按钮,所以我可以执行它们)
- Visual Studio 向我抛出错误(荷兰语文本的翻译:“未找到会员不良习惯”)
提前感谢您对此问题的任何评论和/或解决方案。
namespace AnimalShelter{
[Serializable()]
abstract public class Animal : ISellable, IComparable<Animal>, ISerializable
{
/// <summary>
/// The chipnumber of the animal. Must be unique. Must be zero or greater than zero.
/// </summary>
public int ChipRegistrationNumber { get; private set; }
public abstract decimal Price { get; }
/// <summary>
/// Date of birth of the animal.
/// </summary>
public SimpleDate DateOfBirth { get; private set; }
/// <summary>
/// The name of the animal.
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Is the animal reserved by a future owner yes or no.
/// </summary>
public bool IsReserved { get; set; }
/// <summary>
/// Creates an animal.
/// </summary>
/// <param name="chipRegistrationNumber">The chipnumber of the animal.
/// Must be unique. Must be zero or greater than zero.</param>
/// <param name="dateOfBirth">The date of birth of the animal.</param>
/// <param name="name">The name of the animal.</param>
public Animal(int chipRegistrationNumber, SimpleDate dateOfBirth, string name)
{
if (chipRegistrationNumber < 0)
{
throw new ArgumentOutOfRangeException("Chipnummer moet groter of gelijk zijn aan 0");
}
ChipRegistrationNumber = chipRegistrationNumber;
DateOfBirth = dateOfBirth;
if (name == null)
{
throw new ArgumentNullException("Naam is null");
}
Name = name;
IsReserved = false;
}
/// <summary>
/// Retrieve information about this animal
///
/// Note: Every class inherits (automagically) from the 'Object' class,
/// which contains the virtual ToString() method which you can override.
/// </summary>
/// <returns>A string containing the information of this animal.
/// The format of the returned string is
/// "<ChipRegistrationNumber>, <DateOfBirth>, <Name>, <IsReserved>"
/// Where: IsReserved will be "reserved" if reserved or "not reserved" otherwise.
/// </returns>
public override string ToString()
{
string IsReservedString;
if (IsReserved)
{
IsReservedString = "reserved";
}
else
{
IsReservedString = "not reserved";
}
string info = ChipRegistrationNumber
+ ", " + DateOfBirth
+ ", " + Name
+ ", " + IsReservedString;
return info;
}
private Animal(SerializationInfo info, StreamingContext context)
{
ChipRegistrationNumber = (Int32)info.GetValue("Chipnumber", typeof(Int32));
DateOfBirth = (SimpleDate)info.GetValue("Date of Birth", typeof(SimpleDate));
Name = (String)info.GetValue("Name", typeof(String));
IsReserved = (bool)info.GetValue("Isreserved", typeof(bool));
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Chipnumber", ChipRegistrationNumber);
info.AddValue("Date of Birth", DateOfBirth);
info.AddValue("Name", Name);
info.AddValue("Isreserved", IsReserved);
}
public int CompareTo(Animal other)
{
throw new NotImplementedException();
}
}
狗
namespace AnimalShelter
{
[Serializable]
public class Dog : Animal
{
/// <summary>
/// The date of the last walk of the dog. Contains null if unknown.
/// </summary>
public SimpleDate LastWalkDate { get; set; }
/// <summary>
/// Creates a dog.
/// </summary>
/// <param name="chipRegistrationNumber">The chipnumber of the animal.
/// Must be unique. Must be zero or greater than zero.</param>
/// <param name="dateOfBirth">The date of birth of the animal.</param>
/// <param name="name">The name of the animal.</param>
/// <param name="lastWalkDate">The date of the last walk with the dog or null if unknown.</param>
public Dog(int chipRegistrationNumber, SimpleDate dateOfBirth,
string name, SimpleDate lastWalkDate) : base(chipRegistrationNumber, dateOfBirth, name)
{
if (lastWalkDate != null)
{
this.LastWalkDate = lastWalkDate;
}
}
/// <summary>
/// Retrieve information about this dog
///
/// Note: Every class inherits (automagically) from the 'Object' class,
/// which contains the virtual ToString() method which you can override.
/// </summary>
/// <returns>A string containing the information of this animal.
/// The format of the returned string is
/// "Dog: <ChipRegistrationNumber>, <DateOfBirth>, <Name>, <IsReserved>, <LastWalkDate>"
/// Where: IsReserved will be "reserved" if reserved or "not reserved" otherwise.
/// LastWalkDate will be "unknown" if unknown or the date of the last doggywalk otherwise.
/// </returns>
public override string ToString()
{
// TODO: Put your own code here to make the method return the string specified in the
// method description.
if (LastWalkDate == null)
{
return $"Dog: {base.ToString()} - unknown";
}
return $"Dog: {base.ToString()}, {LastWalkDate}";
}
public override decimal Price
{
get
{
if(ChipRegistrationNumber < 50000)
{
return 200;
}
return 350;
}
}
public new void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Lastwalk", LastWalkDate);
}
public Dog(SerializationInfo info, StreamingContext context) : base(info, context)
{
LastWalkDate = (SimpleDate)info.GetValue("Lastwalk", typeof(SimpleDate));
}
}
猫
namespace AnimalShelter
{
[Serializable]
public class Cat : Animal
{
/// <summary>
/// Description of the bad habits that the cat has (e.g. "Scratches the couch").
/// or null if the cat has no bad habits.
/// </summary>
public string BadHabits { get; set; }
/// <summary>
/// Creates a cat.
/// </summary>
/// <param name="chipRegistrationNumber">The chipnumber of the animal.
/// Must be unique. Must be zero or greater than zero.</param>
/// <param name="dateOfBirth">The date of birth of the animal.</param>
/// <param name="name">The name of the animal.</param>
/// <param name="badHabits">The bad habbits of the cat (e.g. "scratches the couch")
/// or null if none.</param>
public Cat(int chipRegistrationNumber, SimpleDate dateOfBirth,
string name, string badHabits) : base(chipRegistrationNumber, dateOfBirth, name)
{
this.BadHabits = badHabits;
}
/// <summary>
/// Retrieve information about this cat
///
/// Note: Every class inherits (automagically) from the 'Object' class,
/// which contains the virtual ToString() method which you can override.
/// </summary>
/// <returns>A string containing the information of this animal.
/// The format of the returned string is
/// "Cat: <ChipRegistrationNumber>, <DateOfBirth>, <Name>, <IsReserved>, <BadHabits>"
/// Where: IsReserved will be "reserved" if reserved or "not reserved" otherwise.
/// BadHabits will be "none" if the cat has no bad habits, or the bad habits string otherwise.
/// </returns>
public override string ToString()
{
// TODO: Put your own code here to make the method return the string specified in the
// method description.
if (String.IsNullOrEmpty(BadHabits))
{
BadHabits = "none";
}
return $"{"Cat: "}{base.ToString()}, {BadHabits}";
}
public override decimal Price
{
get
{
int korting = BadHabits.Length - 60;
if ( korting > 20)
{
return korting;
}
return 20;
}
}
public new void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("BadHabits", this.BadHabits);
}
public Cat(SerializationInfo info, StreamingContext context) : base(info, context)
{
this.BadHabits = (String)info.GetString("BadHabits");
}
}
}
管理
public void Save(String fileName)
{
Stream fileStream = File.Open(fileName, FileMode.Create);
BinaryFormatter format = new BinaryFormatter();
format.Serialize(fileStream, Animals);
fileStream.Close();
}
public void Load(String fileName)
{
FileStream fileStream;
BinaryFormatter format = new BinaryFormatter();
fileStream = File.OpenRead(fileName);
Animals = (List<Animal>)format.Deserialize(fileStream);
fileStream.Close();
}
【问题讨论】:
-
你能把狗和猫的课程也发上来吗?
-
您实际上想在这里做什么?重要的是:
ISerializable、BinaryFormatter等 - 应该被认为是过时且非常危险的,所以如果你不是绝对 100% 与BinaryFormatter绑定:任何其他 seiralizer 都会是一个巨大的进步。如果您能具体说明为什么要使用BinaryFormatter,我们或许可以提供更多建议。 -
不相关:
if (name == null)您可能要考虑使用string.IsNullOrWhitespace(string)。 -
@Fildor 谢谢,我疏忽了。
标签: c# inheritance serialization interface deserialization