我是编程新手,但我需要序列化数据,我首先读取 csv 并根据所述 csv 中的数据创建类。当我单击按钮时,列表应该被序列化以供以后使用。
这是 Dealership (del) 和 Car 类的代码:
[DataContract]
public class Dealership
{
[DataMember]
private List<Car> carList = new List<Car>();
public void ImportCars()
{
carList.Clear();
var fileContent = string.Empty;
var filePath = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.InitialDirectory = "c:\\";
openFileDialog.Filter = "csv files (*.csv)|*.csv";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filePath = openFileDialog.FileName;
using (var reader = new StreamReader(filePath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Read();
csv.ReadHeader();
while (csv.Read())
{
var record = new Car
{
Model = csv.GetField("model"),
Brand = csv.GetField("brand"),
Year = Convert.ToInt32(csv.GetField("year")),
Price = Convert.ToDecimal(csv.GetField("price"))
};
carList.Add(record);
}
}
}
}
}
}
[DataContract]
public class Car
{
[DataMember]
private string brand;
[DataMember]
private string model;
[DataMember]
private int year;
[DataMember]
private decimal price;
public string Brand { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public decimal Price { get; set; }
}
这是表单代码:
Dealership del1 = del;
FileStream? fs = null;
try
{
fs = new FileStream("dealership.xml", FileMode.OpenOrCreate, FileAccess.Write);
Type mainType = typeof(Dealership);
//List<Type> auxiliryTypes = new List<Type>() { typeof(Car), typeof(Customer) };
DataContractSerializer dcs = new DataContractSerializer(mainType);
dcs.WriteObject(fs, del1);
}
finally
{
if (fs!=null) fs.Close();
}
XML 输出片段:
<Dealership xmlns="http://schemas.datacontract.org/2004/07/Individual_Assignment" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><carList><Car><brand i:nil="true"/><model i:nil="true"/><price>0</price><year>0</year></Car>
当我通过在表单中输入客户详细信息来销售汽车时,XML 怎么可能不包含汽车的任何值,它会序列化这些值,但不会序列化其他值。
最佳答案
根据经验,让数据传输对象 (DTO) 类(即用于序列化的类)仅具有公共(public)属性。您可能还应该使用通用集合:
[DataContract]
public class Dealership {
[DataMember]
public List<Car> CarList {get;set;} = new List<Car>();
}
使用公共(public)属性往往适用于大多数序列化库。可能存在异常(exception),有些可以处理私有(private)属性,有些可以处理不可变类型,但是您需要检查您的库支持哪些特定语法。我不记得 DataContractSerializer 的确切规则。
另请注意,您可能应该将 DTO 类与域类分开,这样您在实际使用对象时不必公开内部字段,只有在与系统的其他部分通信时才需要公开内部字段。
我还建议设置一个单元测试来序列化和反序列化您的类。这是查看哪些有效、哪些无效的简单方法。如果您担心的话,它还可以用于检查旧版本的类是否仍然正确地反序列化。
完整示例:
[DataContract]
public class Car
{
[DataMember]
public string Brand { get; set; }
[DataMember]
public string Model { get; set; }
[DataMember]
public int Year { get; set; }
[DataMember]
public decimal Price { get; set; }
}
[DataContract]
public class Dealership
{
[DataMember]
public List<Car> Cars { get; set; } = new ();
};
[Test]
public void ShouldSerializeAndDeserialize()
{
var sut = new DataContractXml();
var car = new Car(){Brand = "Volvo", Model = "v70", Price = 20000, Year = 2004};
var dealer = new Dealership();
dealer.Cars.Add(car);
using var ms = new MemoryStream();
var serializer = new DataContractSerializer(typeof(Dealership));
serializer.WriteObject(ms, dealer);
ms.Position = 0;
var result = (Dealership)serializer.ReadObject(ms);
Console.WriteLine(result.Cars[0].Brand);
}
关于C# 序列化不会向 xml 文件中的属性添加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75081234/