首页 > 解决方案 > 在一个类中保存多个类的不同属性

问题描述

我正在从一本名为“C# 7 and .Net Core: Modern Cross-Platform Development - Second Edition”的书中做一个问题,最后给出的练习没有提供解决方案。

问题概述:

创建一个名为 Ch10_Exercise02 的控制台应用程序,该应用程序创建一个形状列表,使用序列化将其保存到使用 XML 的文件系统,然后将其反序列化:

// create a list of Shapes to serialize 
var listOfShapes = new List<Shape> 
{ 
  new Circle { Colour = "Red", Radius = 2.5 }, 
  new Rectangle { Colour = "Blue", Height = 20.0, Width = 10.0 }, 
  new Circle { Colour = "Green", Radius = 8 }, 
  new Circle { Colour = "Purple", Radius = 12.3 }, 
  new Rectangle { Colour = "Blue", Height = 45.0, Width = 18.0  } 
}; 

形状应该有一个名为 Area 的只读属性,以便在反序列化时可以输出形状列表,包括它们的区域,如下所示:

List<Shape> loadedShapesXml = serializerXml.Deserialize(fileXml)
as List<Shape>; 
foreach (Shape item in loadedShapesXml) 
{ 
  WriteLine($"{item.GetType().Name} is {item.Colour} and has an
  area of {item.Area}"); 
} 

这是运行应用程序时输出的样子:

Loading shapes from XML:
Circle is Red and has an area of 19.6349540849362
Rectangle is Blue and has an area of 200
Circle is Green and has an area of 201.061929829747
Circle is Purple and has an area of 475.2915525616
Rectangle is Blue and has an area of 810

我制作了一个 Shape 类,其中包含继承自它的 Circle 和 Rectangle 类。

class Shape
{
    public readonly double Area;
}

class Circle : Shape
{
    public string Colour { get; set; }
    public double Radius { get; set; }
    Area = Radius* Radius * Math.PI;
}

class Rectangle : Shape
{
    public string Colour { get; set; }
    public double Height { get; set; }
    public double Width { get; set; }
    Area = Width * Height;
}

我不确定为什么我的 Circle 和 Rectangle 类无法识别继承的 Area 字段。是因为 Circle 和 Rectangle 应该以某种方式合并到一个 Shape 类中吗?

编辑:这个文档帮助我找到了答案

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-define-abstract-properties

标签: c#

解决方案


首先,public readonly double Area;不是财产。这是一个领域。要创建只读属性,您将创建一个 getter-only 属性,如下所示:public double Area { get; }

接下来,我很确定Area = Radius* Radius * Math.PI;会导致编译器错误。如果你需要重写 Area 的实现,我会在你的父类中将 Area 设为一个虚拟属性,然后在你的子类中重写它,如下所示:

class Shape
{
    public virtual double Area { get;}
}

class Circle : Shape
{
    public string Colour { get; set; }
    public double Radius { get; set; }
    public override double Area
    {
        get { return Radius * Radius * Math.PI; }
    }
}

推荐阅读