我一直在自学C#,而我正在学习如何使用自定义数据类型。我正在编写的程序产生了一对坐标对。我认为创建一个包含每个集合(x1,x2,y1,y2)的数据类型以及与该集合相关的一些其他变量是一个巧妙的想法。但是,程序将生成多个坐标集(不同类别),因此跟踪事物仍然很困难。然后我将其进一步细分为类别,并将每个类别置于第三个类别下,作为第三个级别,然后将其放入列表中。
项目的每个“层”都有一些特定于该层的属性,但在此障碍之前,我没有任何需要在层次结构之间交换数据。当我意识到我需要使用偏移来修改坐标对集合时,问题出现了,并且每个偏移都特定于父数据类型。我可以修改get {}代码来返回数据加上偏移量(我称之为“skew”),但是如果偏移量来自数据类型的类本身之外则不行。我尝试在父数据类型中设置一个值(即使是公共静态数据类型),但由于某种原因,孩子无法读取它。
我知道如何使这项工作的唯一方法是在每个坐标集中设置属性,但可能有数千个。该值对于父级是唯一的,但是所有孩子都需要使用它,因此这似乎很浪费,因为会有很多其他计算正在进行。我的另一个想法是维护一个偏移数组,并将其添加到检索值的位置。但是,这并不像在数据类型本身中包含它那样干净,因此会增加混乱。还有另一种方法可以实现这个目标吗?
以下是一些代码的外观:
public class SlotData
{
private double _x1, _x2, _y1, _y2;
public double X1
{
get { return _x1; }
set { _x1 = value; }
}
public double X2
{
get { return _x2; }
set { _x2 = value; }
}
public double Y1
{
get { return _y1; }
set { _y1 = value; }
}
public double Y2
{
get { return _y2; }
set { _y2 = value; }
}
}
public class ClientInfo
{
public static double _skewX, _skewY;
public SlotGroup1 Group1
{
get;
set;
}
public SlotGroup2 Group2
{
get;
set;
}
public SlotGroup3 Group3
{
get;
set;
}
}
public class SlotGroup1
{
public SlotData Slot1
{
get;
set;
}
public SlotData Slot2
{
get;
set;
}
}
答案 0 :(得分:1)
public class SlotData
{
private SlotData() { }
public SlotData(SlotGroupBase group)
{
this._group = group;
}
private SlotGroupBase _group;
public double X1 { get; set; }
public double X2 {get; set;}
public double Y1 {get; set;}
public double Y2 {get; set;}
public double NewX1
{
get
{
return _group.ClientInfo._skewX + X1;
}
}
}
public class ClientInfo
{
public double _skewX, _skewY;
public SlotGroup1 Group1 { get; set; }
}
public abstract class SlotGroupBase
{
private SlotGroupBase() { }
public SlotGroupBase(ClientInfo ci)
{
this._ci = ci;
}
private ClientInfo _ci;
public ClientInfo ClientInfo
{
get
{
return _ci;
}
}
}
public class SlotGroup1 : SlotGroupBase
{
public SlotGroup1(ClientInfo ci):base (ci) {}
public SlotData Slot1 { get; set; }
public SlotData Slot2 { get; set; }
}
static void Main(string[] args)
{
ClientInfo ci = new ClientInfo();
SlotGroup1 sg1 = new SlotGroup1(ci);
sg1.Slot1 = new SlotData(sg1);
sg1.Slot2 = new SlotData(sg1);
Console.ReadLine();
}
在您的代码中,您没有父数据类型或后代数据类型。因此,除了您将引用某种类型的对象实例之外,某些类型的成员无法以任何方式访问其他类型。
但面向对象的编程可以帮助你。如果SlotGroupN
类型中的每一个都必须引用ClientInfo
,那么基类SlotGroupBase
将包含对ClientInfo
的引用是值得的。另外,您应该将SlotData
类型引用添加到SlotGroupBase
。在这种情况下,您将访问像
return _group.ClientInfo._skewX + X1;
另一个好主意是限制自己和其他开发人员创建SlotGroupN
类实例而不参考ClientInfo
,SlotData
类项而不引用SlotGroup
。要实现这一点,您应该将默认构造函数设为私有,并添加带参数ClientInfo
public SlotGroupBase(ClientInfo ci)
答案 1 :(得分:0)
扩展你的设计......
using System.Drawing;
public class SlotData
{
private PointF _one;
private PointF _two;
internal SizeF Skew {get; set;}
public PointF One
{
get
{
return PointF.Add(_one, Skew);
}
set {_one = value; }
}
public PointF Two
{
get
{
return PointF.Add(_two, Skew);
}
set {_two = value; }
}
}
public class SlotGroup : List<SlotData>
{
internal SizeF Skew
{
set
{
foreach(var slotData in this)
{
slotData.Skew = value;
}
}
}
}
public class ClientData : List<SlotGroup>
{
private SizeF _skew;
public SizeF Skew
{
get { return _skew; }
set
{
_skew = value;
foreach (var slotGroup in this)
{
slotGroup.Skew = value;
}
}
}
}
我想不出任何更优雅的东西会起作用。封装规定包含的类不能访问其容器的数据,并且覆盖容器类上的子加法器的代码会更加麻烦。