Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类组合作为实例变量_C#_Oop_Uml_Composition - Fatal编程技术网

C# 类组合作为实例变量

C# 类组合作为实例变量,c#,oop,uml,composition,C#,Oop,Uml,Composition,我有一个名为WageInfo的类,它与收入和扣除类有组合关系。所以我实现如下 class WageInfo { int ID {get; set;} Earning E = new Earning(); Deduction D = new Deduction(); } public List<Earning> PrepareEarnings(DateTime wagePeriodStartDate, DateTime wagePeriodEndDate)

我有一个名为
WageInfo
的类,它与
收入
扣除
类有组合关系。所以我实现如下

class WageInfo
{
    int ID {get; set;}
    Earning E = new Earning();
    Deduction D = new Deduction();

}
 public List<Earning> PrepareEarnings(DateTime wagePeriodStartDate, DateTime wagePeriodEndDate)
        {
            return GetEarningsToList(wagePeriodStartDate,wagePeriodEndDate);
        }


        public List<Earning> GetEarningsToList(DateTime startDate, DateTime endDate)
        {
            return CalculateEarnings(startDate,endDate).Rows.OfType<DataRow>().Select(CreateEarnings).ToList();
        }

        private DataTable CalculateEarnings(DateTime startDate, DateTime endDate)
        {
            return _DataService.GetEarnings(startDate,endDate);
        }

        private Earning CreateEarnings(DataRow row)
        {
            WageInfo wageInfo = new WageInfo();

            wageInfo.Earning.EmployeeID = row[0] == DBNull.Value ? 0 : Convert.ToInt32(row[0]);
            wageInfo.Earning.WorkDays = row[2] == DBNull.Value ? 0 : Convert.ToInt32(row[2]);

            //

            return wageInfo.Earning;
        }
我知道我还没有在
WageInfo
构造函数中初始化这些对象,因此不可能将参数传递给
Earning
演绎的
构造函数

除此之外,这可以被视为构成吗?这种方法还有其他缺陷吗

编辑:

有关类的更多详细信息

class Earning
{
int ID {get; set;}
Decimal Amount {get; set;}
DateTime Period {get; set;}

}

class Deduction
{
int ID {get; set;}
Decimal Amount {get; set;}
DateTime Period {get; set;}
String Remarks {get; set;}
}
我访问这些属性如下

class WageInfo
{
    int ID {get; set;}
    Earning E = new Earning();
    Deduction D = new Deduction();

}
 public List<Earning> PrepareEarnings(DateTime wagePeriodStartDate, DateTime wagePeriodEndDate)
        {
            return GetEarningsToList(wagePeriodStartDate,wagePeriodEndDate);
        }


        public List<Earning> GetEarningsToList(DateTime startDate, DateTime endDate)
        {
            return CalculateEarnings(startDate,endDate).Rows.OfType<DataRow>().Select(CreateEarnings).ToList();
        }

        private DataTable CalculateEarnings(DateTime startDate, DateTime endDate)
        {
            return _DataService.GetEarnings(startDate,endDate);
        }

        private Earning CreateEarnings(DataRow row)
        {
            WageInfo wageInfo = new WageInfo();

            wageInfo.Earning.EmployeeID = row[0] == DBNull.Value ? 0 : Convert.ToInt32(row[0]);
            wageInfo.Earning.WorkDays = row[2] == DBNull.Value ? 0 : Convert.ToInt32(row[2]);

            //

            return wageInfo.Earning;
        }
在Program.cs中

WageInfo WI= new WageInfo();
WI.E.Amount= 1000;
EDIT2:

我的班级关系是这样的

WageInfo
可能有许多
收入
扣减
s和
WageBalances
。因此,我的
WageManager
课程中的
PrepareEarnings()
如下所示

class WageInfo
{
    int ID {get; set;}
    Earning E = new Earning();
    Deduction D = new Deduction();

}
 public List<Earning> PrepareEarnings(DateTime wagePeriodStartDate, DateTime wagePeriodEndDate)
        {
            return GetEarningsToList(wagePeriodStartDate,wagePeriodEndDate);
        }


        public List<Earning> GetEarningsToList(DateTime startDate, DateTime endDate)
        {
            return CalculateEarnings(startDate,endDate).Rows.OfType<DataRow>().Select(CreateEarnings).ToList();
        }

        private DataTable CalculateEarnings(DateTime startDate, DateTime endDate)
        {
            return _DataService.GetEarnings(startDate,endDate);
        }

        private Earning CreateEarnings(DataRow row)
        {
            WageInfo wageInfo = new WageInfo();

            wageInfo.Earning.EmployeeID = row[0] == DBNull.Value ? 0 : Convert.ToInt32(row[0]);
            wageInfo.Earning.WorkDays = row[2] == DBNull.Value ? 0 : Convert.ToInt32(row[2]);

            //

            return wageInfo.Earning;
        }
公共列表准备警告(DateTime wagePeriodStartDate、DateTime wagePeriodEndDate)
{
返回GetEarningsToList(wagePeriodStartDate、wagePeriodEndDate);
}
公共列表GetEarningsToList(日期时间开始日期、日期时间结束日期)
{
返回CalculateArnings(startDate,endDate).Rows.OfType().Select(CreateEarnings.ToList();
}
专用数据表计算警告(日期时间开始日期、日期时间结束日期)
{
return _DataService.GetEarnings(开始日期、结束日期);
}
私人收入创造收入(数据行)
{
WageInfo WageInfo=新的WageInfo();
wageInfo.Earning.EmployeeID=行[0]==DBNull.Value?0:转换为32(行[0]);
wageInfo.Earning.WorkDays=第[2]行==DBNull.Value?0:转换为第32行(第[2]);
//
返回下注信息。收益;
}

当包含对象(此处为WageInfo)的完全控制包含的对象(E,D)的生命周期时,关联就是合成

E和D是在WageInfo中确定创建的,因此对于合成来说是可以的。我想他们也会从WageInfo中删除,所以这足以说明这种关系是合成的

此外,它们不应该从包含对象(私有数据成员)的外部直接可见

编辑零件的注释:


您应该使E和D成员成为私有成员,以便使合成更干净。至少有一个能干的人能胜任这项工作。这不是强制性的,但是生命周期控制是基本的。

因此,据我所知,在这种情况下,在构造函数之外初始化变量是否有效是一个潜在的问题。以下是我的建议:

由于WageInfo的变化取决于收入和扣除额,因此不应在构造函数之外使用初始化。你可以问为什么不呢?那么,如果收入或扣除额发生变化会怎样

WageInfo WI= new WageInfo();
WI.E.Amount= 1000;
这会很快变得难看。然而: 如果您不更改这些变量,那么您的方法是有效的。一般来说,每当我不打算对变量进行更改时,我都会使用这种类型的初始化,例如,我可以将其设置为只读

在所有其他情况下,我建议使用(或者至少是一种简单的形式)。所以,在你的情况下,你可以

Earnings earnings = new Earnings(1000);
Deduction deduction = new Deduction(0);
WageInfo info = new WageInfo(earnings,deduction)
编辑:如下面的评论所述,最好将构建的责任交给WageInfo类本身。可以在创建相应对象的位置添加AddArnings/AddDeclarations方法

WageInfo info = new WageInfo();
info.AddEarnings(100);
此外,正如@Aleks所提到的,至少使用私有setter是个好主意。通过如下方式声明属性来执行此操作:

public Earning { get; private set; }

我不确定您是否提供了足够的信息来说明这是一个好的结构还是一个坏的结构。从我个人的角度来看,这看起来不错……所有这些成员都是私人的。这就是你所需要的吗?是的,这可以被认为是组成。关于缺陷:这不一定是错误的做法,因此您可以使用这种类型的初始化。此外,您还可以传递参数(例如匿名类型)。评论,因为我不确定这是否是您想要知道的;-)请查看编辑以了解更多详细信息。谢谢,哪些成员应该是私人的?包含对象的成员(私有收入E=新收入())或包含对象(私有十进制金额{get;set;})?E和D应该是私有的(包含对象)WageInfo=新的WageInfo(收入,扣除)-这不符合合成的基本要求-生命周期控制。在这个解决方案中,E和D在包含对象的外部创建,并在其上下文之外存在,就像正常关联一样。在这种情况下,正确的方法是将E和D结构移动到WageInfo内部,类似于WageInfo.addE(1000)->现在WegInfo控制E本身,而不是外部实体。我同意WageInfo Constructor不是E和D创作的最佳选择,因为他们可以自由选择added@Aleks我不熟悉构图的确切定义。我只是指出了一种不同的、可能更有效的方法。我完全同意你的建议,即将施工移至WageInfo(例如,WageInfo.AddE(…)。谢谢你指出这一点。很酷,我刚刚指出了组合关系的重要性,正如查图兰加告诉“这是一个组合”并问“它是否可以被视为一个组合”:)实际上在我的
WageInfo
类中,我只有作为模型类的属性。所有与薪资处理相关的行为都在WageManager类中。(如
CalcEarning()
calcdeducation()
等)。那么把这个AddE()放在哪里呢。我将用图表编辑这篇文章。谢谢