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

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

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

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