1

I had to do a test which I passed mainly to the MCQ part but my coding part is not working and since our instructor is not too keen on giving the feedback I would love to learn about my mistakes and improve from that. The explaining comments are in the code.

In the class Program I get two errors (technically three but one is the same as the other). In the line with "Console.WriteLine("Commission is: ", item.CalculateComission);" I get: "CS1061 'double' does not contain a definition for 'CalculateComission' and no extension method 'CalculateComission' accepting a first argument of type 'double' could be found (are you missing a using directive or an assembly reference?)"

enter image description here

In the line with "GetCheapestResidance(apartments);" I get: "CS1503: Argument 1: cannot convert from 'System.Collections.Generic.List<Test2.Apartment>' to 'System.Collections.Generic.List<Test2.Residence>'

enter image description here

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

namespace Test2
{
    abstract class Residence
    {
        //properties Bedrooms, Bathrooms, Price
        public int Bedrooms { get; set; }

        public int Bathrooms { get; set; }

        public double Price { get; set; }

        //A no-argument constructor that creates a default Residence
        public Residence() 
        {
        
        }

        //A constructor that creates a Residence with the specified bedrooms, bathrooms, price
        public Residence(int bedrooms, int bathrooms, double price) 
        {
            Bedrooms = bedrooms;
            Bathrooms = bathrooms;
            Price = price;
        }

        //CalculateCommission() (public): abstract method with return type: double
        public abstract double CalculateCommission();
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Test2
{
    class Apartment : Residence
    {
        //Properties: Unit and Floor. Both are integer type 
        public int Unit { get; set; }

        public int Floor { get; set; }

        //A no-argument constructor
        public Apartment() { }

        //A constructor that creates a apartment object with the specified bedrooms, bathrooms, price, Unit and Floor
        public Apartment(int unit, int floor, int bedrooms, int bathrooms, double price) : base(bedrooms, bathrooms, price)
        {
            Unit = unit;
            Floor = floor;
        }

        //Override CalculateCommission() method. The commission rate for an apartment is set up at 3%
        public override double CalculateCommission()
        {
            return Price * 0.03;
        }

        //toString() that returns the information about the current object
        public override string ToString()
        {
            return $" Bedrooms: {Bedrooms}\n" +
                $"Bathrooms: {Bathrooms}\n" +
                $"Floor: {Floor}\n" +
                $"Unit: {Unit}\n" +
                $"Price: {Price}";
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Test2
{
    class House : Residence
    {
        //Propeties:  Stories and Basement.Stories is integer type, Basement is Boolean type, 
        //indicating whether the house has basement
        public int Stories { get; set; }

        public bool Basement { get; set; }

        //A no-arg constructor
        public House() { }

        //A constructor that creates a house object with the specified bedrooms, 
        //bathrooms, price, stories, basement

        public House(int stories, bool basement, int bedrooms, int bathrooms, double price) : base(bedrooms, bathrooms, price)
        {
            Stories = stories;
            Basement = basement;
        }

        //toString() that returns the information about the apartment
        public override string ToString()
        {
            return $" Bedrooms: {Bedrooms}\n" +
                $"Bathrooms: {Bathrooms}\n" +
                $"Stories: {Stories}\n" +
                $"Basement: {Basement}\n" +
                $"Price: {Price}";
        }

        //Override CalculateCommission() method. The commission rate for a house is set up at 3.5%
        public override double CalculateCommission()
        {
            return Price * 0.035;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;

namespace Test2
{
    class Program
    {

        public static void GetCheapestResidance(List<Residence> list)
        {
            //finds the cheapest residence in the list (either in the houses list or apartments list ) 
            //depending on the parameter that you will pass. 
            var item = list.Min(x => x.Price);

            //then display the information about the cheapest residence using ToString()
            Console.WriteLine("The cheapest is: ", item.ToString());

            //and display the commission
            Console.WriteLine("Commission is: ", item.CalculateComission);
        }

        static void Main(string[] args)
        {
            List<House> houses = new List<House>();
            List<Apartment> apartments = new List<Apartment>();

            //Create three house objects  and three apartment object with data of your choice. 
            //Then add them to the the above lists.

            Residence ap1 = new Apartment(101, 1, 1, 1, 1100);
            Residence ap2 = new Apartment(102, 2, 2, 1, 1500);
            Residence ap3 = new Apartment(103, 3, 3, 2, 1900);

            Residence hs1 = new House(1, false, 2, 1, 1500);
            Residence hs2 = new House(1, true, 3, 1, 1900);
            Residence hs3 = new House(2, true, 4, 1, 2300);
                        
            apartments.Add((Apartment)ap1);
            apartments.Add((Apartment)ap2);
            apartments.Add((Apartment)ap3);

            houses.Add((House)hs1);
            houses.Add((House)hs2);
            houses.Add((House)hs3);

            //Invoke GetCheapestResidance method by passing either houses list OR department list

            GetCheapestResidance(apartments);

            GetCheapestResidance(houses);

            Console.ReadKey();
        }
    }
}

Alan Shore
  • 93
  • 7
  • 1
    Error message suggests you have `double.caclulateCommission` or `double_var.calculateCommission` somewhere in your code – John3136 Aug 26 '20 at 00:05

3 Answers3

3

To answer your first question, note the wording of the error: "CS1061 'double' does not contain a definition for 'CalculateComission'". This error states that you have a variable which is of type double which you are trying to call CalculateComission() on. The error occurs here:

var item = list.Min(x => x.Price);
Console.WriteLine("Commission is: ", item.CalculateComission);

Notice that you did not specify the type of item and instead just said var item. Your error occurs because the Min function returns the minimum value given to it. In this case, you are giving the function a list of Prices. As such, the item variable is actually of type double, not Residence. As such, you are trying to call CalculateCommission() on a number, instead of calling it on the Residence.

To answer your second question, you cannot just use a List<Apartment> as a List<Residence>. Note the following fixed code:

//a list of residences instead of a list of apartments
List<Residence> apartments = new List<Residence>(); 

//Because Apartment is a Residence, you can make these variables Apartment or Residence
Apartment ap1 = new Apartment(101, 1, 1, 1, 1100); 
Residence ap2 = new Apartment(102, 2, 2, 1, 1500);
Apartment ap3 = new Apartment(103, 3, 3, 2, 1900);

apartments.Add(ap1);
apartments.Add(ap2);
apartments.Add(ap3);

//This time the function call is valid because GetCheapestResidance() expects a                 
List<Residence>
//and that is what we are passing in
GetCheapestResidance(apartments);

Because your Apartment class extends Residence, you can simply create a List<Residence> as your apartment list and add the apartments to it as usual. This should fix the issue of passing a List<Apartment> into a function which expects a List<Residence>.

piggyBot
  • 132
  • 6
1

All good questions.

I'll go through one at a time:

  1. The error with the double is because your var item = list.Min(... returns a minimum value after iterating through your list. It returns the minimum number it found of price not the object that owns that vale.

    To fix this you can use the .Aggregate function. It's a little complicated so I'd recommend looking at this post for full detail: How to use LINQ to select object with minimum or maximum property value . The other way you could do this is with a simple for or foreach loop and keep track of the lowest value and its owner as you iterate through.

  2. The reason this method GetCheapestResidence is complaining is because it is expecting a list of Residences whereas you provide a list of Apartments. You cannot case these lists to one another unfortunately, which I believe is a limitation of lists (if anyone knows why please comment below). So you must provide the correct list type here. You already create new Apartments that are referenced by Residences so why not combine those Residences into their own list?

         List<House> houses = new List<House>();
         List<Residence> apartments = new List<Residence>();
    
         //Create three house objects  and three apartment object with data of your choice. 
         //Then add them to the the above lists.
    
         Residence ap1 = new Apartment(101, 1, 1, 1, 1100);
         Residence ap2 = new Apartment(102, 2, 2, 1, 1500);
         Residence ap3 = new Apartment(103, 3, 3, 2, 1900);
    
         Residence hs1 = new House(1, false, 2, 1, 1500);
         Residence hs2 = new House(1, true, 3, 1, 1900);
         Residence hs3 = new House(2, true, 4, 1, 2300);
    
         apartments.Add(ap1);
         apartments.Add(ap2);
         apartments.Add(ap3);
    
         houses.Add((House)hs1);
         houses.Add((House)hs2);
         houses.Add((House)hs3);
    
         //Invoke GetCheapestResidance method by passing either houses list OR department list
    
         GetCheapestResidance(apartments);
    

Here I have changed your List to List as with your current code you have no use of a list of apartments. Same goes for houses.

If anyone has any better solutions to this please feel free to comment or edit this.

marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
Josh
  • 141
  • 6
0

For the first error, try concatenating the arguments with a + instead of a comma, and adding parentheses at the end of item.CalculateCommision() to actually get the result of the function. But the main issue is that you're calling a function on a double, not an object. You can change your Min call to do something like list.OrderBy(x => x.Price).FirstOrDefault() to get the residence with the lowest price and return it. For the second error, try changing from a list of apartments to a list of residents to see if that helps. The argument doesn't accept the type you're passing through, but you should be able to add apartment instances into a list of residences.

Tyler
  • 19
  • 1
  • 2