Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

201
Vistas
¿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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda