How to include an instance of Animal in an instance of Dog?

Let's say I have the following classes:

class Animal { public long Id { get; set; } public string Name { get; set; } } class Dog:Animal { public void sniffBum() { Console.WriteLine("sniff sniff sniff"); } } 

If I have an instance of Animal , how do I pass it to Dog ? Something like that:

 Animal a = new Animal(); if ( some logic to determine that this animal is a dog ) { Dog d = (Dog)a; d.sniffBum(); } 

Essentially, I cannot use interfaces. I will always have an Animal object coming out of my database. Dog has no more parameters than Animal has only new methods.

I could just create a new Dog object and pass the values ​​through (or have a constructor that takes the type of Animal ), but that just seems messy.

+6
source share
10 answers

Casting checks will not work if the Animal instance has never been a Dog instance.

You can look at the Decorator Pattern , which allows you to add Dog methods to the Animal instance. Essentially, Dog and Animal have an IAnimal interface. The Dog class takes an instance of Animal in the constructor and stores the internal reference. The implementation of Dog IAnimal simply refers to the instance of Animal that it refers to (which allows Dog be distinct for IAnimal and behave like a wrapped Animal for polymorphism). Dog also has additional methods specific to Dog.

+2
source

To check if an object can be applied to a type, use the is keyword.

 Animal animal = new Dog(); if( animal is Dog) { //your code } 
+3
source

First create the animal as a Dog, then check if it is Dog

 Animal a = new Dog(); if (a is Dog ) { Dog d = (Dog)a; d.sniffBum(); } 
+3
source

You can do this with is , but since you want to name something on any dogs, you will find that it would be better to use as :

 var dog = a as Dog; if (dog != null) { dog.sniffButt(); } 

However, you should be aware that this scheme (an attempt to determine the type of runtime so that you can relate it to something convenient) is usually not approved. You can easily overdo it and end up checking dogs, cats, parrots, fish, turtles ... I'm sure you can visualize the resulting mess.

If your needs point to this scenario, a much better solution is to use the Visitor design pattern.

+2
source

An animal can never be a dog.

Create your Dog constructor by using the Animal parameter.

 class Dog : Animal { public Dog(Animal a) { this.Name = a.Name; this.Id = a.Id; } public void sniffBum() { Console.WriteLine("sniff sniff sniff"); } } 
+1
source

I do not work like that. Casting is an operation that interprets an instance as a given type; it will not change its type. In your case, you must first determine what animal is in that particular database row, and then create an instance of the correct ancestor. Pseudocode:

 var row = Fetch from database; Animal animal; if (row is a dog) animal = new Dog(); else if (row is a cat) animal = new Cat(); 
0
source

You can do it:

 var dog = a as Dog; if(dog != null) { dog.DoSomething(); } 

it is preliminarily checked if the dog is a Dog, if you need to impose it last. See Next Answer: Casting vs Using the 'as' Keyword in the CLR

0
source

You cannot throw an animal into a dog, it can be a cat! I think that you are trying to create an object of type Dog from another object of type Animal that has been extracted from db.

One way is to accept an object of type Animal in Dog overloaded constructor:

 class Dog:Animal { public Dog(Animal animal) { this.Id = animal.Id; this.Name = animal.Name; } ... } 

So you can simply use the following:

 if ( some logic to determine that this animal is a dog ) { Dog d = new Dog(a); d.sniffBum(); } 
0
source

I would create some static methods for a Dog object or some kind of DogFactory , where you can specify your Animal as a parameter and create it for your dog or return null .

In this method, you can perform character checks on your animals to see if you want it to be a dog (4 legs, a bit, whatever)

Otherwise, it would be difficult to move from an object created as an Animal to a specific Dog object.

0
source

Kamyar is right, there is no way to do this because, as you yourself told us

 i will always have an Animal object coming out of my database like that 

so you need to save the type also in your database

after that you should change Animal to

 public class Animal { public long Id { get; set; } public string Name { get; set; } public string AnimalType { get; private set; } public Animal() { } public Animal(string type) { AnimalType = type; } // to denie self repeading if all animales have the same Properties protected void set(Animal a) { Id = a.Id; Name = a.Name; AnimalType = a.AnimalType; } } 

.

 Dog doesnt have any more parameters than Animal has, only new methods 

so you can change your Dog to

 public class Dog : Animal { public Dog(Animal a) { base.set(a); } public void sniffBum() { Console.WriteLine("sniff sniff sniff"); } } 

.

 i could just create a new Dog object, and pass the values accross, (...), but this just seems messy 

I don’t think there is a way and it doesn’t look dirty

and here how to use an example

  Animal a = new Animal("Dog"); if (a.AnimalType =="Dog") { Dog d = new Dog( a); d.sniffBum(); } 
0
source

Source: https://habr.com/ru/post/943622/


All Articles