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

203
Views
¿Cómo usar la clase abstracta de herencia?

Necesito ayuda con un ejemplo de clase de herencia (resumen). No puedo usar mi función ToCSV() porque devuelvo una lista de BananaPart y C# quiere una lista de FruitPart. ¿Cómo es posible solucionar esto?

 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; } }

¡Será un placer para mí aprender más al respecto! Gracias de antemano !

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

La razón por la que su código no se compila es porque List<T> no es covariante. Para compilar su código, debe cambiar List<T> con IEnumerable<T> , que tiene un parámetro de tipo covariante. Entonces los cambios son:

 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; } } }

Puede obtener más información sobre la covarianza aquí: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/

En resumen, la covarianza le permite deducir la compatibilidad de asignación de dos tipos en función de la compatibilidad de asignación de otros dos tipos. Dado que podemos asignar un BananaPart a un FruitPart , podemos deducir que un IEnumerable<BananaPart> se puede asignar a IEnumerable<FruitPart> .

over 4 years ago · Santiago Trujillo Report

0

Hay un problema en tu modelo. Digamos que tengo un plátano y tiene una lista de partes de frutas. Ahora podría llamar a myBananana.FruitParts.Add(new ApplePart()) , esto no puede funcionar ya que un plátano solo se compone de partes de plátano.

Para evitar esto, debe ser más restrictivo en lo que devuelve. En lugar de usar List<FruitPart> , podría usar IEnumerable<Fruitpart> . Esto evita el problema ya que no puede agregar nada a un IEnumerable .

Si está aprendiendo, también recomendaría comenzar con interfaces en lugar de clases abstractas. La última a veces se denomina "herencia de implementación", es decir, se utiliza para compartir código entre dos clases derivadas. Esto a veces es útil, pero en la mayoría de los casos es mejor poner este código compartido en una tercera clase, a veces llamada "Composición sobre herencia".

Tu fruta podría verse así usando 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); }

Tenga en cuenta que no necesita mucho más código para la variante de interfaz en comparación con el caso de clase abstracta.

over 4 years ago · Santiago Trujillo Report

0

No puede convertir de forma segura List<Child> a List<Parent> porque le permitiría agregar Apple a List<Banana> .

Puede crear List<FuitPart> en su lugar.

 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!