-2

Complete noob to C#, converting from Visual Basic, I have been trying to refence class fields in a separate module, tried everything, no good. Moved everything to one module to minimise the accessibility issues, scoped everything public, still can't access fields/properties. I have boiled this down to absolute basics, still can't get it to work. Have tried every possible variation of accessibility (I think).

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Car MyCar = new Car();
    }
                
    public class Car
    {
        string Manufacturer { get; set; }
        string Model { get; set; }
        int YearMade { get; set; }

    }
    private void button1_Click(object sender, EventArgs e)
    {
        Car.Manufacturer = "Ford"; 
    }

}

Car.Manufacturer in the Click event throws

CS0122 'Form1.Car.Manufacturer' is inaccessible due to its protection level.

If I change the Manufacturer field to public I get this error:

CS0120 An object reference is required for the non-static field, method, or property 'Form1.Car.Manufacturer'

I realise I am doing something stupid here, but how hard can this be?

TheGeneral
  • 79,002
  • 9
  • 103
  • 141
Dodge
  • 17
  • 2
  • 4
    are you trying to do MyCar.Manufacturer = "Ford" ? – psj01 Oct 02 '20 at 23:55
  • 1
    @psjo1 is correct. `Car` is a Class (think blueprint) which can have Objects created that match it's specification. you actually created an object `MyCar` on the form, but instead of updating `MyCar`, you are trying to update `Car`. also note that this is one reason that you will see objects start with a lowercase where classes start with an uppercase, to make the distinction a bit more obvious when scanning through the code. – Claies Oct 03 '20 at 00:00
  • See also: [What are the default access modifiers in C#?](https://stackoverflow.com/questions/2521459/what-are-the-default-access-modifiers-in-c) – gunr2171 Oct 03 '20 at 00:09
  • Just to make sure I haven't lost my mind, I just did this in VB. Works fine. I guess I don't understand how scoping works in C#. Any advice? – Dodge Oct 03 '20 at 01:24
  • Sorry I have used myCar previously, I pasted the wrong unsuccessful attempt into the OP. When it says myCar.Manufacturer = "Ford"; I get this error: CS0103 The name 'myCar' does not exist in the current context That's why I moved the class declaration into the same module, which didnt help. – Dodge Oct 03 '20 at 01:27
  • @Dodge you either have to do what ndogac suggested in the answer below.. or do what I've done in my answer .. simply create an instance of the car in the button1_Click event – psj01 Oct 03 '20 at 01:37

2 Answers2

5

Car is class and Manufacturer is a non-static field. Which means it is an instance field. Which means for every instance of Car, there is a manufacturer. So a Car has a Manufacturer statement is true. To eliminate the error you should create an instance of it. Like this:

var myCar = new Car();
myCar.Manufacturer = "Ford";

Or you can make Your Car a class field in your Form. That means A Form has a Car. The syntax is like this:

public partial class Form1 : Form
{
    private readonly _myCar;
    
    public Form1()
    {
        InitializeComponent();
        
        _myCar = new Car();
    }
                
    public class Car
    {
        string Manufacturer { get; set; }
        string Model { get; set; }
        int YearMade { get; set; }
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        _myCar.Manufacturer = "Ford"; 
    }
}
ndogac
  • 1,185
  • 6
  • 15
  • 3
    Good answer. The only thing I would add it that [it is "bad" practice to use public fields instead of properties](https://softwareengineering.stackexchange.com/a/161308/115084) – John Wu Oct 03 '20 at 00:11
1

You have defined Manufacturer to be a non-static field.

I think what you might want to do is, in your button1_Click event, create an instance of your Car object and set its manufacturer to Ford.

like this:

private void button1_Click(object sender, EventArgs e)
{
    Car MyCar = new Car();
    MyCar.Manufacturer = "Ford"; 
}

Note: also make sure to make your properties public. eg:

public class Car
{
    public string Manufacturer { get; set; }
    public string Model { get; set; }
    public int YearMade { get; set; }
}
psj01
  • 3,075
  • 6
  • 32
  • 63
  • Sorry guys I fixed all that, still throwing an error, can't post code in the comment. – Dodge Oct 03 '20 at 01:59
  • 103. I have a button click event that simply posts myCar.Manufacturer to a txt box. But because that is in a separate procedure (not where myCar is created) it now can’t see it. Everything is public – Dodge Oct 03 '20 at 02:18
  • It’s as if it has procedure scope but not module scope. – Dodge Oct 03 '20 at 02:22
  • Look at the code ndogac posted above. that should fix your problem. I think u just have to make sure your properties are public. – psj01 Oct 03 '20 at 03:08
  • Only 1 property. It's public. – Dodge Oct 03 '20 at 07:51
  • 1
    Back at the computer. Thanks for the help all especially psj01 read the answers properly, it's sorted. – Dodge Oct 03 '20 at 09:44