Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

197
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda