2013-10-09 161 views
2

我有一个看起来像一个简单的问题,但由于某种原因,我有一个问题让我的大脑围绕着一个具有多个对象的对象的概念。例如,假设我们有一个包含页眉和页脚的对象,其中包含多个对象。在一个对象中创建一个对象类

和报告一样,标题的名称和地址也是如此。页脚会包含购买商品的总数。介于两者之间的是包含零件号,说明和价格的订单项。

我想我可以有一个对象的页眉,页脚和一个行项目对象的数组,所有的都有自己的属性。我以报告为例,因为这是我能想到的唯一概念,它将接近解释我的问题。

有人可以给我一个链接或解释如何创建这种类型的对象。

我使用VS 2010和VB.net,我可以从C#转换到VB。

Report Object 
     Header Object 
     Property Name 
     Property Date 
     End 
     LineItem() Array Object 
     Property Part Number 
     Property Part Description 
     Property Number of Items 
     Property Per Item Price 
     Property Total price 
     End 
     Footer Object 
     Property Total Items count 
     Property Total Price 
     End 
    End 
+1

使其更加具体。这实际上是关于报告(序列关键)还是关于课程设计的更普遍? –

+2

这听起来像你有你的答案。具有其属性和表示“LineItems”集合的属性的标头对象。这听起来非常合理。 – Khan

+0

任何具有类属性的解决方案(如下所示)都只能存储内容。任何布局知识(比如:标题都在顶部)必须以其他方式存储。 –

回答

4

杰夫,在C#中,并在其最基本的:

public class Report 
{ 
    // typical simple property in report 
    public string ReportUid { get; set; } 
    // object properties 
    public Header Header { get; set; } 
    public Body Body { get; set; } 
    public Footer Footer { get; set; } 

    public Report() 
    { 
     Header = new Header(); 
     Body = new Body(); 
     Footer = new Footer(); 
    } 

    internal void CalculateFooterTotals() 
    { 
     // summerize the lineitems values in the footer 
     Footer.TotalItems = Body.LineItems 
      .Sum(x => x.Quantity); 
     Footer.TotalPrice = Body.LineItems 
      .Sum(x => x.Total); 
    } 
} 

public class Header 
{ 
    public string Name { get; set; } 
    public DateTime Date { get; set; } 
} 

public class Body 
{ 
    public IList<LineItem> LineItems { get; set; } 

    public Body() 
    { 
     LineItems = new List<LineItem>(); 
    } 
} 

public class LineItem 
{ 
    public string PartNumber { get; set; } 
    public string PartDescription { get; set; } 
    public int Quantity { get; set; } 
    public float ItemPrice { get; set; } 
    // computed 
    public float Total 
    { 
     get { return Quantity * ItemPrice; } 
    } 
} 

public class Footer 
{ 
    // populated via report.CalculateFooterTotals() 
    public int TotalItems { get; internal set; } 
    public float TotalPrice { get; internal set; } 
} 

有些属性是当然的计算,而不是获取/套。

[编辑] - 认为它会是很好的做法,增添几分使用的,因为我看到你问道格拉斯这个问题(不是从数据库或其他来源可能更多):

// usage - set up report 
var report = new Report { 
    ReportUid = Guid.NewGuid().ToString(), 
    Header = 
    { 
     Name = "My new report", 
     Date = DateTime.UtcNow 
    }}; 
// add lineitems to body (in real case, probably a loop) 
report.Body.LineItems.Add(new LineItem() 
    { 
     Quantity = 1, 
     ItemPrice = 12.30f, 
     PartDescription = "New shoes", 
     PartNumber = "SHOE123" 
    }); 
report.Body.LineItems.Add(new LineItem() 
    { 
     Quantity = 3, 
     ItemPrice = 2.00f, 
     PartDescription = "Old shoes", 
     PartNumber = "SHOE999" 
    }); 
report.Body.LineItems.Add(new LineItem() 
    { 
     Quantity = 7, 
     ItemPrice = 0.25f, 
     PartDescription = "Classic Sox", 
     PartNumber = "SOX567" 
    }); 
// summerize the lineitems values in the footer 
report.CalculateFooterTotals(); 

现在申请报告,以你的画布表面(HTML等)

private static void DispalyData(Report report) 
{ 
    // set out the basics 
    Console.WriteLine("Header"); 
    Console.WriteLine(report.ReportUid); 
    Console.WriteLine(report.Header.Date); 
    Console.WriteLine(report.Header.Name); 

    // now loop round the body items 
    Console.WriteLine("Items"); 
    foreach (var lineItem in report.Body.LineItems) 
    { 
     Console.WriteLine("New Item---"); 
     Console.WriteLine(lineItem.PartDescription); 
     Console.WriteLine(lineItem.Quantity); 
     Console.WriteLine(lineItem.ItemPrice); 
     Console.WriteLine(lineItem.PartNumber); 
     Console.WriteLine(lineItem.Total); 
     Console.WriteLine("End Item---"); 
    } 

    // display footer items 
    Console.WriteLine("Footer"); 
    Console.WriteLine(report.Footer.TotalItems); 
    Console.WriteLine(report.Footer.TotalPrice); 
} 

// called in code as: 
DispalyData(report); 

希望这将扫描好的...它推到社区维基(通过修改),因为它是话题后普遍追捧。

[BTW] - 本书虽然你会知道C#来vb.net转换器,我想这一个,它看起来非常有前途:http://www.developerfusion.com/tools/convert/csharp-to-vb

+0

谢谢吉姆,这真的可以帮助我理解和试验你答案的用法。尽管我真正的问题要复杂得多,但这确实有助于我让自己的大脑围绕班级和该班的重复部分进行。我相信除了这个以外,还有更多的东西可以用来学习一般的课程,但是这会让我走。我还有一个问题,我看到如何定义它并加载它,如何输出它?比方说把它显示到控制台上。 – Jeff

+0

jeff ...让我添加一个快速显示部分... –

+0

神奇的吉姆!! ... ..这完全解释了基础知识,并一定会帮助别人。谢谢你在这里的时间。 – Jeff

3

您需要为每种类型的对象创建一个类。最好给他们每个人自己的文件。

Public Class Report 
    Public Property Header As Header 
    Public Property LineItems As IEnumerable(Of LineItem) 
    Public Property Footer As Footer 
End Class 


Public Class Header 
    Public Property Name As String 
    ' This probably isn't the best word choice because it is a type alias in VB 
    Public Property [Date] As Date 
End Class 


Public Class LineItem 
    Public Property PartNumber As Integer 
    Public Property PartDescription As String 
    Public Property NumberOfItems As Integer 
    Public Property PerItemPrice As Decimal 
    Public Property TotalPrice As Decimal 
End Class 


Public Class Footer 
    Public Property TotalItemsCount As Integer 
    Public Property TotalPrice As Decimal 
End Class 

使用它,像这样:

Dim myReport As New Report() 
Dim myHeader As New Header() 
Dim lineItem1 As New LineItem() 
Dim lineItem2 As New LineItem() 
Dim myFooter As New Footer() 
With myReport 
    .Header = myHeader 
    .Footer = myFooter 
    .LineItems = {lineItem1, lineItem2} 
End With 
+0

谢谢道格拉斯 - 你能告诉我如何初始化和添加项目到lineitem? – Jeff

+0

你有几种方法。您可以为每个构造函数创建一个构造函数并初始化其中的属性,也可以使用默认构造函数并手动设置属性。 –

+0

另外,您不能将项目添加到'IEnumerable',因为它没有'.Add'方法。如果要添加到ICollection中,您需要将其更改为“ICollection”。 –