首页 > 解决方案 > 如何在C#中访问嵌套在父类中的子类项

问题描述

我正在使用一个公共类 Orders 结构,用于将数据传递给 API Post。结构定义为:

public class Orders{
  public string OrderID {get; set;}

  public class ShipTo {
      public string Address1 {get;set;}
      public string Address2 {get;set;}
  } 
}

在我的代码中,我使用: Orders orders = new Orders();

然后我可以访问类 orderID:orders.OrderId = 123;

然后对于 ShipTo 我设置:

 Orders.ShipTo shipping = new Orders.ShipTo();

并且可以使用添加地址

 shipping.address1 = "my first street";

伟大的。现在我想将整个 Orders 类传递给一个函数,该函数将读取 OrderId 和 Shipping 地址。我不知道如何传递一个让我可以阅读所有内容的参考。我认为合乎逻辑的事情是:

  thisOrder = orders.OrderId;
  thisShipAddress = orders.shipping.address1;

这是行不通的。感谢您的洞察力。

标签: c#class

解决方案


你混淆了类和实例。我建议您完全避免将一个类嵌套在另一个类中;它是你学习的一个积极障碍,你可能永远不会在你的编码生活中需要使用嵌套类

因此更改您的代码:

//in file Order.cs
public class Order{
  public string OrderID {get; set;}

  public Address ShipTo {get; set;}
  public Address BillTo {get; set;}
}

//in file Address.cs
public class Address {
  public string Address1 {get;set;}
  public string Address2 {get;set;}
}

在这里,我在某物什么(一个类,如地址)和它的含义(属性的名称,如您的 ShipTo 与您的 BillTo 的地址)之间做出了明确的区分

ShipTo 和 BillTo 都是 Address,它们可能是同一个地方,也可能是不同的,但它们有不同的用途。属性的名称反映了数据的用途,而类的名称表示数据的结构/真实世界对象或概念的建模对象

现在您将它们设置为:

Order o = new Order();
o.OrderId = 1234;

o.ShipTo = new Address();
o.ShipTo.Address1 = "One Microsoft Way";
o.ShipTo.Address2 = "Redmond";

//this uses an initializer to set properties; same thing
o.BillTo = new Address () {
  Address1 = "One Infinite Loop",
  Address2 = "Cupertino"
}

您可以使用类似于第一种方式的代码稍后访问您的属性:

public void SomeMethod(Order x){
  x.BillTo.Address2 = "Cuppateanow";
  Console.WriteLine(o.BillTo.Address1);
}

(初始化器有助于简化创建对象,但没有类似的语法用于稍后访问数据,仅用于创建)

请记住,仅仅因为您通过以下方式下订单:

Order o = new Order();

并不意味着它o.BillTo被设置为任何东西。C# 不会为您分层创建所有内容。如果您创建订单但未创建 BillTo 地址,然后尝试访问 BillTo 地址,您将收到 NullReferenceException。o.BillTo = new Address()在尝试之前,您必须确保已完成o.BillTo.Address1 = ""


边注; 同意艾米的观点。避免使用复数形式的类名。如果一个类是事物的集合,你应该以“Collection”结束它的名字,除非它的名字表明它是一个集合(如 List、Hashset)

作为单个实体的属性应该有一个单数名称 public string OrderId ...

作为集合的属性应该有一个复数名称

public List<Address> Addresses ...

在后一种情况下,您的类可能有一个枚举来说明它是什么类型的地址,然后一个订单可以有任意数量的任何类型的地址,这非常灵活——也许您会编写只允许一个运输和计费但您将向与订单相关的每个通信地址发送订单更新:

enum AddressType{
    Shipping,
    Billing,
    Correspondence
}

class Address{
    ...
    public AddressType AddressType ...
}

(或者我们可以将地址子类化..但我将把这个讨论留到另一个时间)


推荐阅读