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

124
Views
¿Miembros de tipo abstracto en C#?

Me encantan los miembros de tipo abstracto de Scala , que es una gran característica.

Por ejemplo, considere este ejemplo simple, tal como se ingresó en Scala REPL:

 scala> :paste // Entering paste mode (ctrl-D to finish) /** Base class for a pet food class. */ abstract class PetFood /** Dog food. */ final class DogFood extends PetFood /** Cat food. */ final class CatFood extends PetFood /** An abstract Pet. */ abstract class Pet { /** Type of food this pet will eat. */ type Food <: PetFood /** Eat some food. */ final def eat(food: Food): Unit = println("Yum!") } /** A dog. */ final class Dog extends Pet { // Dogs require dog food. override type Food = DogFood } /** A cat. */ final class Cat extends Pet { // Cats require cat food. override type Food = CatFood } // Exiting paste mode, now interpreting. defined class PetFood defined class DogFood defined class CatFood defined class Pet defined class Dog defined class Cat scala> val dog = new Dog dog: Dog = Dog@2036f83 scala> dog.eat(new DogFood) Yum! scala> dog.eat(new CatFood) <console>:14: error: type mismatch; found : CatFood required: dog.Food (which expands to) DogFood dog.eat(new CatFood) ^

Tanto el Dog como el Cat siguen siendo tipos de Pet y se pueden usar donde sea que se requiera una Pet , pero tienen requisitos alimenticios específicos. Pero el punto clave es que Pet sigue siendo polimórfica.

Estoy tratando de hacer algo similar en C# (en la versión 7.2), pero, por lo que sé, parece no ser compatible con el concepto de miembros de tipo abstracto (o incluso miembros de tipo).

Lo que me gustaría evitar es convertir a Pet en genérico, porque eso destruiría el polimorfismo. Por ejemplo:

 public abstract class PetFood { } public sealed class DogFood: PetFood { } public sealed class CatFood: PetFood { } public abstract class Pet<F> where F: PetFood { public void Eat(F food) => Console.WriteLine("Yum!"); } public sealed class Dog: Pet<DogFood> { } public sealed class Cat: Pet<CatFood> { }

Esto funciona en términos de garantizar que las mascotas coman el tipo correcto de comida, pero Pet ya no es polimórfica (no puedo pasar una instancia de Dog o Cat cuando se requiere una instancia de Pet , porque necesito un argumento genérico para las instancias de Pet ) .

¿Hay alguna manera de lograr esto en C# ? (¿O un lenguaje .NET alternativo?)

(Mi caso de uso real es un poco más complejo que esto, pero estoy tratando de mantener la explicación simple. Basta con decir que no es suficiente crear una clase base no genérica para la jerarquía).

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Lo que hago en situaciones como esta es separar las cosas no genéricas en una clase abstracta, no genérica, Pet, y hacer que Pet se derive de ella. Realmente no tiene sentido pasar polimórficamente una mascota a un lugar que pretende llamar al método Eat.

También puede hacer que todos los métodos o tipos que usan Pet sean genéricos, pero eso no ayuda con las colecciones.

over 4 years ago · Santiago Trujillo Report

0

No estoy 100% seguro de tu objetivo, pero tal vez algo como esto ayude:

 public interface IFood<T> { string Brand { get; } } public class Pet<T> { public void Eat(IFood<T> food) { Console.WriteLine(food.Brand); } } public class DogFood : IFood<Dog> { public string Brand => "Dog Deli"; } public class CatFood : IFood<Cat> { public string Brand => "Lucky Cat"; } public class Dog : Pet<Dog> {} public class Cat : Pet<Cat> {} (new Dog()).Eat(new DogFood()); (new Cat()).Eat(new CatFood()); // (new Cat()).Eat(new DogFood()); <-- won't compile

Editar: agregue una clase que acepte cualquier mascota

 public class PetChecker { public void CheckPet<T>(Pet<T> pet) { Console.WriteLine(pet.GetType().Name); } } new PetChecker().CheckPet(new Dog()); // output: "Dog"
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!