Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

194
Views
How to use Inheritance Abstract Class?

I need some help with an example of Inheritance class (abstract). I can't use my function ToCSV() because i return a list of BananaPart and C# wants a list of FruitPart. How is it possible to solve this ?

using System;
using System.Collections.Generic;
                    
public class Program
{
    public static void Main()
    {
        FruitFactory fruitFactory = new FruitFactory();
        Fruit myFruit = fruitFactory.Create("banana");
        
        myFruit.FruitPart.ForEach(f => Console.WriteLine(f.ToString()));
    }
}

public class FruitFactory {
    public Fruit Create(string fruitType) { 
        switch(fruitType) {
            case "banana":
                return new Banana();
                break;
            default:
                throw new Exception("undefined fruitType");
        }   
    }
}

public abstract class Fruit {
    protected string _name;
    protected List<FruitPart> _fruitPart;
    
    public Fruit() {
        this._name = "A fruit";
    }
    
    public string Name { get { return this._name; } }
    public List<FruitPart> FruitPart { get { return this._fruitPart; } }
}

public abstract class FruitPart { }

public class Banana : Fruit {
    public Banana() : base() {
        this._name = "banana";
        this._fruitPart = ToCSV();
    }
    
    public List<BananaPart> ToCSV(){
        return new List<BananaPart> { new BananaPart(5, "10"), new BananaPart(10, "20"), new BananaPart(20, "40") };
    }
}

public class BananaPart : FruitPart {
    private int _seed;
    private string _dimensionPart;
    
    public BananaPart (
        int seed,
        string dimensionPart
    ) {
        this._seed = seed;
        this._dimensionPart = dimensionPart;
    } 
}

It will be a pleasure for me to learn more about it ! Thank you in advance !

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

The reason that your code is not compiling is because List<T> is not covariant. In order to compile your code you need to change List<T> with IEnumerable<T> which has a covariant type parameter. So the changes are:

public abstract class Fruit {
    protected string _name;
    protected IEnumerable<FruitPart> _fruitPart;

    public Fruit() {
      this._name = "A fruit";
    }

    public string Name { get { return this._name; } }
    public IEnumerable<FruitPart> FruitPart { get { return this._fruitPart; } }
}

You can learn more about covariance here: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/

In short, covariance lets you deduce the assignment compatibility of two types based on the assignment compatibility of two other types. Since, we can assign a BananaPart to a FruitPart, we can deduce that a IEnumerable<BananaPart> can be assigned to IEnumerable<FruitPart>.

over 4 years ago · Santiago Trujillo Report

0

There is a problem in your model. Say I have a Banana, and it has a list of fruit-parts. Now I could call myBananana.FruitParts.Add(new ApplePart()), this cannot work since a banana is only composed of bananaparts.

To avoid this you need to be more restrictive in what you return. Instead of using a List<FruitPart> you could use IEnumerable<Fruitpart>. This avoids the problem since you cannot add anything to a IEnumerable.

If you are learning I would also recommend starting with interfaces instead of abstract classes. The later is sometimes called "Implementation inheritance", i.e. it is used to share code between two derived classes. This is sometimes useful, but in the majority of cases it is better to put this shared code in a third class, sometimes called "Composition over inheritance".

Your fruit could ook something like this using interfaces:

public interface IFruit
{
    string Name { get; }
    IEnumerable<IFruitPart> FruitPart { get; }
}
public class Banana : IFruit
{
    public Banana() : base() => FruitPart = ToCSV();
    public static List<BananaPart> ToCSV() => new List<BananaPart> { new BananaPart(5, "10"), new BananaPart(10, "20"), new BananaPart(20, "40") };
    public string Name { get; } = "Banana";
    public IEnumerable<IFruitPart> FruitPart { get; }
}
public interface IFruitPart { }
public class BananaPart : IFruitPart
{
    public int Seed { get; }
    public string DimensionPart { get; }
    public BananaPart(int seed, string dimensionPart) => (Seed, DimensionPart) = (seed, dimensionPart);
}

Notice that you do not need much more code for the interface variant compared to the abstract class case.

over 4 years ago · Santiago Trujillo Report

0

You cannot safely cast List<Child> to List<Parent> because it would let you add Apple to List<Banana>.

You can create List<FuitPart> instead.

    public List<FruitPart> ToCSV()
    {
        return new List<FruitPart> { 
            new BananaPart(5, "10"), 
            new BananaPart(10, "20"), 
            new BananaPart(20, "40") };
    }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!