【问题标题】:How do you make a nested class that can access the members of the class that created it?你如何创建一个可以访问创建它的类的成员的嵌套类?
【发布时间】:2011-01-18 13:28:56
【问题描述】:

我正在使用 C#.NET 进行编程。我想创建一个嵌套类,它可以访问创建它的实例的成员,但我似乎无法弄清楚如何。

这就是我想做的:

Car x = new Car()
x.color = "red";
x.Door frontDoor = new x.Door();
MessageBox.Show(frontDoor.GetColor());    // So I want the method GetColor of the class Front Door to be able to access the color field/property of the Car instance that created it.

我该怎么做?我尝试将 Door 类嵌套在 Car 类中,但它无法以这种方式访问​​ Car 类的成员。我需要让 Car 继承门类吗?

【问题讨论】:

  • 顺便说一句,使用嵌套类对权限有重要影响(这意味着只有非常紧密耦合的类才应该嵌套)。特别是,在汽车中嵌套一扇门将使门可以访问汽车类的私人成员。这可能不是你想要的。如果门类只在车内使用(即类是私人的),这会稍微不那么可怕......但只有一点点。但你可能也不希望这样。
  • 布莱恩+1。框架设计指南(又名 .NET 圣经)很好地反对使用嵌套类;除了少数少数例外,应避免使用它们。
  • 你们会再看一下这个问题吗?我添加了更多细节。
  • 我已将此回复为人们实际回答的问题,因为新问题已移至stackoverflow.com/questions/2297605/…

标签: c# class nested abstract inheritance


【解决方案1】:

最简单的方法是为 Door 类型提供对创建它的 Car 的引用。

例如:

class Car { 
  public string color;
  public Door Door() { return new Door(this); }
  class Door { 
    Car owner;
    Door(Car owner) { this.owner = owner; }
    string GetColor() { return owner.color; }
  }
}

【讨论】:

  • -1 这使得 DOOR 对象依赖于 CAR 对象。在您需要将 DOOR 放入 TRUCK 对象之前,这可能会正常工作。
  • public Door() { return new Door(this); } // 在第 3 行。你能解释一下,这是在做什么吗?
  • 我同意您所做的更改,但不喜欢您将 Door 嵌套在 Car 类中,原因我在对原始问题的评论中提到。
  • @Asad:没什么,它不能编译。我也不确定他想在那里做什么。
  • @Jeffrey,所以你对我投了反对票,因为用户给出了一个糟糕的示例场景?否决用户的错误设计,而不是我给出正确的解决方案。
【解决方案2】:

这真的不是一个嵌套类,而是一个Door 类型的对象,它被Car 类型的对象的属性所引用。由于 C#(以及大多数其他面向对象的语言)中的引用本质上是单向的,因此您还需要在另一个方向上添加引用,以便能够执行您正在尝试的操作。

这是一种可能的实现:向Door 添加一个构造函数,接受对Car 的引用作为参数。构造函数应该将引用保存在private readonly 字段中。在GetColor()方法中,使用引用获取Car实例的color

然后,考虑将 GetColor() 替换为 get-only Car 上的 Door 属性。根据您在真实课程中的关系(我假设您并不是真正的汽车模型),这可能会或可能不会更可取。

【讨论】:

    【解决方案3】:

    这通常不是您在设计良好的对象模型中想要做的事情。

    DOOR 是 CAR 对象的一个​​组件,但不应依赖于 CAR 对象。您应该通过构造函数或通过 DOOR 的 setter 属性将 CAR 的颜色传递给 DOOR。

    【讨论】:

    • 对象的组件知道其父级是完全合理的。
    • @Brian - 在一般意义上你是正确的。我会定义一个接口 IVehicle 并将其传递给 Door 的构造函数。
    • 哦,我完全同意使用嵌套来访问汽车的私有变量是可怕的。我只是说能够在父级上调用 GetColor() 并非不合理。
    【解决方案4】:

    如果你想在 Door 类中访问 Car 的私有成员需要使用继承,如果你只想访问 Door 类中 Car 的公共成员可以使用 Composition

    像这样:

    public class Car
        {
            public string Color;
        }
    
        public class Door
        {
            public string T;
    
            public Car C;
        }
    

    虽然这不是一个真正合乎逻辑的方法。应该是 Car 类里面有一个 Door 属性。

    【讨论】:

      【解决方案5】:

      我会让 Door 类在其构造函数中使用 Func<Color>,而 Car 类可以通过它传递 GetColor() 方法:

      public class Car
      {
          private class Door
          {
              public Door(Func<Color> getColourFunc)
              {
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        我认为门根本不应该与汽车有任何关系。该关系应该是模型作为关联 - “拥有”关系。汽车应该拥有车门,甚至在创建汽车时负责创建车门。门的构造函数应该接受一个参数来说明要创建什么颜色的门,例如 door = new Door(this.Colour);其中“this”是对当前汽车对象的引用。如果您从逻辑上考虑,我可以将汽车颜色更改为蓝色,然后我的门颜色将随之更改。但是,如果我决定将车门颜色设为红色,则无需更改汽车颜色。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-06
          • 1970-01-01
          • 2019-11-15
          • 1970-01-01
          • 1970-01-01
          • 2017-12-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多