C#在运行时修改自定义数据类型的返回

时间:2012-02-14 08:23:32

标签: c# custom-data-type

我一直在自学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;
        }
    }

2 个答案:

答案 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类实例而不参考ClientInfoSlotData类项而不引用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;
            }
        }
    }
}

我想不出任何更优雅的东西会起作用。封装规定包含的类不能访问其容器的数据,并且覆盖容器类上的子加法器的代码会更加麻烦。