-1

I am just learning C# using Microsoft Virtual Academy. Here is the code I am working with:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Variables
{
    class Program
    {
        static void Main(string[] args)
        {
            Car myCar = new Car("BWM", "745li", "Blue", 2006);
            printVehicleDetails(myCar);
            Console.ReadLine();
        }
    }  

    abstract class Vehicle
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public int Year { get; set; }
        public string Color { get; set; }

        public abstract string FormatMe();

        public static void printVehicleDetails(Vehicle vehicle)
        {
            Console.Writeline("Here are the vehicle's details: {0}", vehicle.FormatMe());
        }
    }

    class Car : Vehicle
    {
        public Car(string make, string model, string color, int year)
        {
            Make = make;
            Model = model
            Color = color;
            Year = year;
        }

        public override string FormatMe()
        {
            return string.Format("{0} - {1} - {2} - {3}",
                this.Make,
                this.Model,
                this.Color,
                this.year);
        }
    }

Anyway, the problem I am having stems from the line printVehicleDetails(myCar). When I try to build the project, I get the error "The name 'printVehicleDetails' does not exist in the current context.

I can fix the error by changing the line to Vehicle.printVechicleDetails(myCar).

Does anyone know why I have to include Vehicle in that line?

Loofer
  • 6,841
  • 9
  • 61
  • 102
J Petersen
  • 162
  • 1
  • 13
  • Because it's required by the C# standards? How would the compiler know which method are you referring to? – walther Jan 20 '15 at 17:50
  • You are calling it in a class called `Program`, but the method is a static method in the class `Vehicle`. How do you expect it to know where to find the method? The real question is why do you have it as a static method instead of an instance method anyway? – Matt Burland Jan 20 '15 at 17:51
  • @walther I'm new to C# and all OOP, how was I supposed to know this? – J Petersen Jan 20 '15 at 19:54
  • @MattBurland I am following along with "C# Fundamentals for Absolute Beginners" on MVA. After re-watching the video, it looks like PrintVehicleDetails was supposed to be a function in Program and not in Vehicle. – J Petersen Jan 20 '15 at 20:01
  • @JPetersen: That would make a lot more sense. – Matt Burland Jan 20 '15 at 20:09

3 Answers3

5

Because printVehicleDetails is a static method on the Vehicle class. When you call a static method (on a class other than the one you're in) you need to include the class name so the compiler knows which method to bind to.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • Not 100% sure but i think that is supposed to change with c# 6.0 – Franck Jan 20 '15 at 18:33
  • @Franck: there will be an option to import static methods (with a variant of the `using` statement) from a class into the global namespace, but it won't just happen automatically. – siride Jan 20 '15 at 18:37
2

printVehicleDetails is a static method. To access it, you have to tell it where the method is, which is why changing it to Vehicle.printVehicleDetails works.

Alternatively, you could remove static from the signature of printVehicleDetails and remove the need to pass a vehicle parameter and then call it via myCar.printVehicleDetails();.

public void printVehicleDetails()
{
    Console.Writeline("Here are the vehicle's details: {0}", this.FormatMe());
}

By the way, printVehicleDetails doesn't confirm to the generally accepted C# naming standards. It should be PrintVehicleDetails().

mason
  • 31,774
  • 10
  • 77
  • 121
1

You have printVehicleDetails as a static method, which means that it belongs to the class as a whole and not to an instance, such as your myCar variable. What you have works as is, but it's not ideal. In the object-oriented world, we want to have methods that operate on objects, rather than global methods (which is essentially what static methods are). That is, instead of having a method that takes a dog and makes it bark, we have a method that is called on the dog so that the dog can bark itself.

In order to fit into that paradigm, I would get rid of printVehicleDetails altogether and just use FormatMe. It would look like this in your Main method:

Car myCar = new Car("BWM", "745li", "Blue", 2006);
Console.WriteLine("Here are the vehicle's details: " + myCar.FormatMe());
Console.ReadLine();
siride
  • 200,666
  • 4
  • 41
  • 62