0

I'm new to C# and coming from Java, the syntax is a little bit different. I am trying to return a double of an element in an arrayList.

    public ArrayList vehicleList { get; set; }

class Vehicle
{
    //A vehicle can be a car and must have an ID, a price and a licenseplate number.
    public int iD { get; set; }
    public double price { get; set; }
    public string licensePlate { get; set; }
    public typeVehicle type;

    //Constructor of vehicle, type of vehicle will be parsed from string to enum.
    public Vehicle(int iD, string typeName, double price, string license)
    {
        this.iD = iD;
        this.type = (typeVehicle)Enum.Parse(typeof(typeVehicle), typeName);
    }
}

    //Get the price of the vehicle with parameter ID.
    public double getPriceVehicle(int iD)
    {
        if (iD >= 0 && iD < vehicleList.Count)
        {
            foreach (Vehicle vehicle in vehicleList)
            {
                return vehicleList.Contains(iD).price;
            }
        }
    }

The problem is that I get an error on the return line, and I can't find any solution online for this exactly. Any help would be appreciated.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
Aleathia
  • 53
  • 6
  • Thank you, everybody that answered on this post. I ultimately went the simplest solution because that's the one I understood. The answer using LINQ I understand too but that is something I don't need to learn yet in my course. I purposely made iD and the place in the array the same because for now its just easier, this also mean that the first vehicle will have an iD of 00. – Aleathia Feb 14 '17 at 15:13

3 Answers3

2
List<Vehicle> vehicleList { get; set; }

//Get the price of the vehicle with parameter ID.
public double GetPriceVehicle(int id)
{
    var result = vehicleList.FirstOrDefault(v => v.ID == id);
    if (result == null) 
    {
        throw new NotImplementedException(String.Format("Vehicle with ID={0} was not found", id)); //todo: put in the logic you want for when no vehicle has the given id
    }
    return result.Price;
}

1) Use a Generic List of type Vehicle (System.Collections.Generic.List<Vehicle>) instead of an ArrayList. See here for more: ArrayList vs List<> in C#

2) You're using ID as both an ID and an Index. i.e. An ID is a value assigned to a specific vehicle, which should remain the same regardless of whether you add or remove other vehicles; i.e. it's an identifier. An Index is the number of an item in the list. To give an example, if I'm in a queue of cars at a drive through and the car at the front of the queue pulls away then by them leaving my index changes; i.e. I go from being 5th in the queue to 4th. On the other hand, if I'm talking to my insurance company and they say my car's on file as #3265, should they lose a customer I wouldn't expect them to write to me saying that my ID's now #3264, and that all my documentation with this reference number would now need to be updated.

3) The Where logic here uses something called a lambda expression; i.e. we're searching through all vehicles in the list for one which has an ID which matches the ID passed into the function. This lambda expression could be placed in an actual Where statement (e.g. Where(v => v.ID == id).FirstOrDefault()), but FirstOrDefault allows us to include the lambda expression in it directly anyway. https://msdn.microsoft.com/en-us/library/bb397687.aspx

4) The FirstOrDefault says that if we find a result we stop searching (i.e. we're not expecting a second vehicle on the same ID, so don't waste time looking after we've found one). The Default part of FirstOrDefault says if we don't find a match, return the default value for this type; default(Vehicle); which given Vehicle is a reference type (i.e. a class), is null. https://msdn.microsoft.com/pt-br/library/bb909042(v=vs.90).aspx

5) If result is null we can't return result.Price; that would error as a null object has no properties. An error's fine; but not necessarily that helpful; better to throw an error of our own detailing the issue; we can then add logic to handle that error in a sensible way in any code calling this method. https://msdn.microsoft.com/en-us/library/ms173163.aspx

6) I also changed some of the variable/property names; e.g. iD to ID. Generally anything public should be in pascalCase; anything private/local should be in camelCase. https://msdn.microsoft.com/en-us/library/ms229043(v=vs.100).aspx

7) I didn't implement it here, but a better option may be a generic Dictionary (Dictionary<long, Vehicle>); as this data structure is optimised for fast retrieval, so rather than searching through each item in a list to find a match, uses a hashtable to quickly find the data associated with the given key/ID.
http://geekswithblogs.net/blackrabbitcoder/archive/2011/06/16/c.net-fundamentals-choosing-the-right-collection-class.aspx

Community
  • 1
  • 1
JohnLBevan
  • 22,735
  • 13
  • 96
  • 178
2

Contains returns a Boolean. Boolean does not have a price member.

In Java style you would do this:

//Get the price of the vehicle with parameter ID.
public double getPriceVehicle(int iD)
{
    if (iD >= 0 && iD < vehicleList.Count)
    {
        foreach (Vehicle vehicle in vehicleList)
        {
            if (vehicle.iD == iD) return vehicle.price;
        }
    }
    return 0;
}

But in C# we have the power of LINQ!

public List<Vehicle> vehicleList { get; set; }

class Vehicle
{
    //A vehicle can be a car and must have an ID, a price and a licenseplate number.
    public int iD { get; set; }
    public double price { get; set; }
    public string licensePlate { get; set; }
    public typeVehicle type;

    //Constructor of vehicle, type of vehicle will be parsed from string to enum.
    public Vehicle(int iD, string typeName, double price, string license)
    {
        this.iD = iD;
        this.type = (typeVehicle)Enum.Parse(typeof(typeVehicle), typeName);
    }
}

    //Get the price of the vehicle with parameter ID.
    public double getPriceVehicle(int iD)
    {
        if (iD < 0 || iD >= vehicleList.Count)
           throw new ArgumentOutOfRangeException("iD");

        var vehicle = vehicleList.FirstOrDefault(v => v.iD == iD);
        return vehicle == null ? double.NaN : vehicle.price;
    }
hoodaticus
  • 3,772
  • 1
  • 18
  • 28
1

Is the parameter, iD, the index of the array?

My suggestion would be to use a List instead of an ArrayList.

private List<Vehicle> vehicleList;

public double getVehiclePrice(int index){
    if(index >= 0 && index < vehicleList.Count){
        return vehicleList[index].price;
    }
}
Michael
  • 56
  • 2