What use is this code? - c#

I can't figure out the use for this code. Of what use is this pattern?
[code repeated here for posterity]
public class Turtle<T> where T : Turtle<T>
{
}

This pattern essentially allows you to refer to a concrete subclass within the parent class.
For example:
public abstract class Turtle<T> where T : Turtle<T>
{
public abstract T Procreate();
}
public class SeaTurtle : Turtle<SeaTurtle>
{
public override SeaTurtle Procreate()
{
// ...
}
}
Versus:
public abstract class Turtle
{
public abstract Turtle Procreate();
}
public class SnappingTurtle : Turtle
{
public override Turtle Procreate()
{
// ...
}
}
In the former, it's specified that a SeaTurtle's baby will be a SeaTurtle.

There is no use that I can see. Basically, it's the same as
public class Turtle
{
}

Related

Using abstract class as a generic type

Is there any way to use an abstract class as a generic type? I've given a very simple example below to simulate what I need. I get an error that an implicit conversion cannot be made for variable genericBehavior.
public abstract class AnimalBase { } // Cannot edit
public class Dog : AnimalBase { } // Cannot edit
public class Cat : AnimalBase { } // Cannot edit
public interface IAnimalBehavior<T> where T : AnimalBase { }
public class CatBehavior : IAnimalBehavior<Cat> { }
public class DogBehavior : IAnimalBehavior<Dog> { }
public class Startup
{
public Startup()
{
IAnimalBehavior<Cat> catBehavior = new CatBehavior();
IAnimalBehavior<AnimalBase> genericBehavior = new CatBehavior(); // This doesn't work
}
}
Ultimately, in my .NET Core Startup, I'd like to be able to have the following:
services.AddScoped<IAnimalBehavior<AnimalBase>, CatBehavior>();
or
services.AddScoped<IAnimalBehavior, CatBehavior>();
What's the best approach?
Since are using IAnimalBehavior<AnimalBase>, and not IAnimalBehavior<Cat>, then this structure works:
public interface IAnimalBehavior{ }
public class CatBehavior : IAnimalBehavior { }
public class DogBehavior : IAnimalBehavior { }
...
services.AddScoped<IAnimalBehavior, CatBehavior>();
Having IAnimalBehavior<T> makes sense if you differentiate on T:
public class CatBehavior : IAnimalBehavior<Cat> { }
public class DogBehavior : IAnimalBehavior<Dog> { }
...
services.AddScoped<IAnimalBehavior<Cat>, CatBehavior>();
services.AddScoped<IAnimalBehavior<Dog>, CatBehavior>();

Passing inherited class

I'm trying some simple code to understand the generics in C#. The purpose of the code here is to have a trainer that has her own animal and will ask it to do various stuff (for the sake of the example, to jump).
The problem is with the constructor of the trainer. I would like to be able to pass a Dog, or a Cat. They both inherit from the same class, but because I specified the type definition it seems I can't pass them as argument, they can't be both valid. Is there a way to specify a generic class like "Animal" so I could pass a dog or a cat and keep it as a member?
class AnimalDefinition
{
public Fur Fur;
}
class DogDefinition : AnimalDefinition
{
public BarkSound Bark;
}
class CatDefinition : AnimalDefinition
{
public MeowSound Meow;
}
class Animal<TDefinition> where TDefinition : AnimalDefinition
{
public TDefinition Definition;
public void Jump()
{
Console.WriteLine("Jump.");
}
}
class Dog : Animal<DogDefinition>
{
public Dog(DogDefinition def)
{
Definition = def;
}
}
class Cat : Animal<CatDefinition>
{
public Cat(CatDefinition def)
{
Definition = def;
}
}
class Trainer
{
Animal _animal;
public Trainer(Animal myAnimal)
{
_animal = myAnimal;
}
public MakeJump()
{
_animal.Jump();
}
public Listen()
{
// if T is DogDefinition hear barking
// else if T is CatDefinition hear a meowing, etc
}
}
EDIT: Additional question following Chris Berger's answer (which works, but I didn't change the code to keep the question/answer logical). I added a definition member in the Animal class. Is there any way I can access Bark or Meow from inside the Trainer class or will I have to derivate the class Trainer with CatTrainer : Trainer<CatDefinition>? That is, is there something similar to what we have with classes,
if(T is CatDefinition)
{ // Meowing}
else
{}
I think I agree with the first commenter, that you don't necessarily want generics for this, but assuming you have some other reason for wanting generics...
The solution here is to create a class Animal, which Animal<T> derives from.
For example:
public class Animal
{
public virtual void Jump()
{
Console.WriteLine("Jump.");
}
}
public class Animal<T> : Animal where T : AnimalDefinition
{
public override void Jump()
{
//you can override Jump here if you want to
}
}
public class Dog : Animal<DogDefinition> {}
public class Cat : Animal<CatDefinition> {}
Or, actually, a second option is to give Trainer visibility to the generic parameter:
public class Animal<T> where T : AnimalDefinition
{
public void Jump()
{
Console.WriteLine("Jump.");
}
}
public class Dog : Animal<DogDefinition> {}
public class Cat : Animal<CatDefinition> {}
public class Trainer<T> where T : AnimalDefinition
{
Animal<T> _animal;
public Trainer(Animal<T> myAnimal)
{
_animal = myAnimal;
}
public MakeJump()
{
_animal.Jump();
}
}
And as a tangent... this might be a good place to use a self-referential generic.
public class Animal<T> where T : Animal<T> { }
public class Dog : Animal<Dog> { }
Here's a little more reading on that pattern: https://blogs.msdn.microsoft.com/simonince/2008/06/12/generics-the-self-referencing-generics-pattern/

Accessing field from another class

How is the ModelDuck constructor able to access the fields in the Duck class - flyBehaviour and quackBehaviour. Thanks
namespace HeadFirst
{
public class ModelDuck : Duck
{
public ModelDuck()
{
flyBehaviour = new FlyNoWay();
quackBehaviour = new Quack();
}
public override void display()
{
Console.WriteLine("I am a model duck");
}
}
}
public abstract class Duck
{
public FlyBehaviour flyBehaviour;
public QuackBehaviour quackBehaviour;
public Duck()
{
}
}
The properties belong the the base class.
You should always be able to acces the properties and methods of your base class

Understanding polymorphism in general (c# example)

I am currently in the middle of self-teaching some basic concepts of C# and I am experimenting with abstract classes and polymorphism. I thought I got the basic concept but it turned out that the concept doesn't work like I understood it :). However - I hope I get some answers which clear the dust a little bit :).
The whole task I am trying to achieve is to extend an abstract base class and use the extension with an object of the base class. Like here:
I have an abstract class which implements an abstract property like:
public abstract class BaseClass
{
public abstract MyProperty mP{get;}
}
where the property is
public abstract class MyProperty
{
public abstract string PropertyName{get;}
}
Now I am deriving the MyProperty class for an actual implementation like
public class DerivedProperty : MyProperty
{
public override string PropertyName
{
get
{
return this._name;
}
}
private _name = "Property1";
/* some other implementation follows here...... */
}
As I've understood polymorphism and inheritance it should now be possible to instantiate a derived class from BaseClass and override the property MyProperty with an object of DerivedProperty like this:
public class DerivedClass : BaseClass
{
public override DerivedProperty mP
{
get
{
return dP;
}
}
private DerivedProperty dP = new DerivedProperty();
/* more implementation follows here...... */
}
Because DerivedProperty is an object of MyProperty and DerivedProperty at the same time it is possible to use it where either MyProperty or DerivedProperty is referenced. At least that's what I thought but it seems that this is wrong.
Now I am wondering - why is polymorphism so useful when something like above is not possible? Because even when I try something like this:
public class DerivedClass : BaseClass
{
public override MyProperty mP
{
get
{
return dP as DerivedProperty;
}
}
private DerivedProperty dP = new DerivedProperty();
/* more implementation follows here...... */
}
I still get only my base object MyProperty and not my extended object DerivedProperty which I want to get.
I know why I get those results - I just don't seem logical to me :). Is it really like polymorphism is supposed to work or is my implementation just crap and I have to do it in a different way to get my extended property?
Appreciate your help here!
You have to provide the same type for overrided property. You can use it later in your abstract BaseClass. Parameters as well as return value of member have to be the same when overriding. It is usually not a problem.
I've prepared following examples that my code look similar to yours.
In some scenarios I've seen that there is added second property with more specific type and different (more specific) name:
public abstract class BaseCar
{
public abstract BaseDriver Driver { get; }
}
public abstract class BaseDriver
{
public abstract string Name { get; set; }
}
public class AgressiveDriver : BaseDriver
{
public override string Name { get; set; }
}
public class FastCar : BaseCar
{
private AgressiveDriver _agressiveDriver = new AgressiveDriver();
public override BaseDriver Driver { get { return _agressiveDriver; } }
public AgressiveDriver AgressiveDriver { get { return _agressiveDriver; } }
}
Second approach is to use generics:
public abstract class BaseCar<TDriver>
where TDriver : BaseDriver
{
public abstract TDriver Driver { get; }
}
public abstract class BaseDriver
{
public abstract string Name { get; set; }
}
public class AgressiveDriver : BaseDriver
{
public override string Name { get; set; }
}
public class FastCar : BaseCar<AgressiveDriver>
{
private AgressiveDriver _agressiveDriver = new AgressiveDriver();
public override AgressiveDriver Driver { get { return _agressiveDriver; } }
}
but I think first approach is better because there is no problem with creating/using BaseCar objects (for example to create BaseCar<> variable you have to specify type parameter). Also it makes sense to create more specific name for more specific property.
I think you have an extra bit of complexity you don't need. You have an abstract class inside an abstract class. If you are just learning/relearning this you have skipped a couple easy steps for understanding. Here's a simpler example to start with.
public abstract class Shape
{
public abstract double GetArea();
public abstract double Circumference();
}
public class Square: Shape
{
public double width {get; set;}
public override double GetArea()
{
return width * width;
}
public override Circumference()
{
return width * 4;
}
}
You can now instantiate a Square or create a Circle Class and be able to use either where you use Shape.

Inherit from Interface in generic class

I have the following class:
public class DataInterop <T> where T : ITableAdapter
{
private ITableAdapter tableAdapter;
public DataInterop(T tableAdapter)
{
this.tableAdapter = tableAdapter;
}
}
In the ITableAdapter-Interface are Methods defined like Read(), Write(...), Update(...), Delete(...), ...
Now I want the Class DataInterop to have all Methods from the ITableAdapter interface.
Is it possible for a generic-class to inherit from an interface?
You just need to add : ITableAdaper after the DataInterop<T>
public class DataInterop<T>: ITableAdapter where T: ITableAdapter
{
private ITableAdapter tableAdapter;
public DataInterop(T tableAdapter)
{
this.tableAdapter = tableAdapter;
}
}
(It looks like you're implementing an Adapter Pattern or a Decorator Pattern.)
Yes it is possible, it's especially useful when you handle instances of the class without knowing the concrete type at runtime.
The syntax would be:
public class DataInterop <T> : ITableAdapter where T : ITableAdapter
Ofcourse you can. Sample layout -
public interface IBar
{
string Name { get; set; }
}
public class Foo<T> : IBar
{
public string Name { get; set; }
}

Categories