-1

Hello i have problem with get nested class property value. I want

class Car
{

  string name;
  string model;

  class Engine
  {
    public string engineNumber;

    public Engine(string engineNumber)
    {
      this.engineNumber = engineNumber;
    }

  }

  public Car(string name, string model, string engineNumber)
  {

    this.name = name;
    this.model = model;
    Engine e1 = new engine(engineNumber)
  }

}

In this code I try write Console.Write(c1.e1.engineNumber);in Main class. It is possible get engineNumber value?

Adam
  • 125
  • 11
  • What is `c1`? Your code example is incomplete. Also, you should probably be using properties instead of fields – maccettura Oct 10 '19 at 19:07
  • 2
    Why do you have `Engine` defined a a private inner class? Also you don't do anything with the `Engine` you create in the `Car` constructor. I'd suggest moving `Engine` out of `Car` and adding a `Engine` property to `Car`. – juharr Oct 10 '19 at 19:08

3 Answers3

1

You generally don't want to nest class definitions the way you did. What if you had a car that could use a different kind of engine? Like, say, a 4-liter vs. a 2-liter? Or normally aspirated vs. turbo charged? What you might want to do instead is pass in the Engine as a parameter to the Car.

Regarding your actual problem of obtaining values from these objects, you also need to define how values can be obtained and/or changed. A constructor does the initial work, but what if the Engine or Car have values that need to be changed or obtained during the program's lifestyle? You need accessors.

public class Car
{
    public string name { get; private set; }
    public string model { get; private set; }
    public Engine engine { get; private set; }

    public Car(string name, string model, Engine engine)
    {
        this.name = name;
        this.model = model;
        this.engine = engine;
    }
}

class Engine
{
    public string number { get; private set; }
    // other values as necessary

    public Engine(string number)
    {
        this.number = number;
    }
}

var newCar = new Car('Volvo', 'Hatchback', new Engine('someNumber'));
var engineNumber = newCar.engine.number;

In this example, you can obtain the data you want by referencing an object property (get), but you won't be able to change that data in the same way (private set). Instead, you'd need to make object methods (read: functions, if you're new to OOP) to explicitly change those values.

Major Productions
  • 5,914
  • 13
  • 70
  • 149
0

Yes, you will be able.

But the code you provide losts Engine e1 just after creation since you don't store it at the Car class level.

And the class Engine is private, it should be public.

And its constructor should be internal protected to allow only a Car to create its Engine: internal to prevent other assembly to be able to create one, and protected to allow derived classes even in another assembly to create it.

You can try something like that by changing the getters/setters as you want (I made them public/private, so after creation they can't be mofified by external entities):

static void Main(string[] args)
{
  Car c1 = new Car("Toyota", "Model", "1");
  Console.WriteLine(c1.engine.engineNumber);
}

public class Car
{

  public class Engine
  {
    public string engineNumber { get; private set; }
    internal protected Engine(string engineNumber)
    {
      this.engineNumber = engineNumber;
    }
  }

  public string name { get; private set; }
  public string model { get; private set; }
  public Engine engine { get; private set; }

  public Car(string name, string model, string engineNumber)
  {
    this.name = name;
    this.model = model;
    this.engine = new Engine(engineNumber);
  }

}

If you want to be able to change the engine if it is broken, then the class may be not nested.

  • 1
    Probably should point out that having a class inside a class is usually not the right approach, especially in this case where there seems no reason for it. – maccettura Oct 10 '19 at 19:13
  • Probably depends on if a `Engine` is part of a larger Strategy... is an `Engine` really an interface, based on things like cylinders, aspiration, displacement, HP, etc.? Does the underlying logic of how an `Engine` (or `IEngine`) works important? – Major Productions Oct 10 '19 at 19:18
  • 1
    Putting classes in their own files is generally the preferred way to structure things. You are making a big assumption that the `Engine` class will never be needed by anything other than `Car` (and maybe OP is too). This is why it seems like a good learning opportunity for the OP – maccettura Oct 10 '19 at 19:19
  • The question I have asked is not about a specific problem. I'm just starting to learn with programming and I came up with the idea of ​​whether it is possible to do something like that, but in the documentation I couldn't answer the question – Adam Oct 11 '19 at 18:37
0

Many ways to accomplish it, here is mine :), the trick is to differentiate class declaration from class implementation.

using System;

public class Program
{
  public static void Main()
  {
    var c = new Car("Name", "Model", "Engine");
    Console.WriteLine(c.engine.engineNumber);
  }

  class Car
  {
    string name;
    string model;
    public Engine engine;

    public Car(string name, string model, string engineNumber)
    {
      this.name = name;
      this.model = model;
      this.engine = new Engine(engineNumber);
    }
  }

  class Engine
  {
    public string engineNumber;
    public Engine(string engineNumber)
    {
      this.engineNumber = engineNumber;
    }
  } 
}

You can see it running here: https://dotnetfiddle.net/66lGn6

Mauricio Atanache
  • 2,424
  • 1
  • 13
  • 18