Override child class inherited property with more derived type
NOTE: This answer was written in 2016. Return type covariance has (amazingly!) been added to C# in the years since. Keep that in mind when reading this answer.
The feature you want is called return type covariance, and C# does not support it. (C++ does, incidentally.)
The usual case made for covariant return types is:
abstract class Animal
{
public abstract Cage GetCage();
}
public class Fish : Animal
{
public override Aquarium GetCage() { ... }
}
This is not legal, but if it were legal it would be safe. That is, if you have an Animal in hand and you ask for a cage, you get one, even if it is a fish. Why? Because an aquarium is a kind of cage.
What you propose though is not only illegal, it's unsafe:
Animal animal = new Mouse();
animal.Teeth = new TRexTeeth();
The contract is that the setter can be called with any kind of tooth. By making the derived class more restrictive in what it can accept, you violate the contract of the base class.
So don't do that.
There are a bunch of ways though that you can achieve what you want in C#.
Here's just one of them:
interface IAnimal
{
Teeth Teeth { get; } // READ ONLY
}
class Mouse : IAnimal
{
private SmallTeeth smallTeeth;
public SmallTeeth Teeth
{
get { return smallTeeth; }
}
Teeth IAnimal.Teeth { get { return this.Teeth; } }
}
Now if you cast a mouse to IAnimal you get the property that returns Teeth, and if you use a mouse normally you get the property that returns SmallTeeth.
I describe another way to solve this problem here:
Does C# support return type covariance?
And the generic solution given in the other answer also works, though personally I prefer to keep generics out of it unless necessary.
Do a search on "return type covariance in C#" for more information on this pattern.
Actually yes. You could but should not use generics
for that purpose including a type constraint (see comments below and the post of Eric Lippert who explains in detail, what you are wanting or trying to achieve in your situation):
public class Animal<T> where T : Teeth
{
public virtual T teeth {get;set;}
}
public class Mouse : Animal<SmallTeeth>
{
public override SmallTeeth teeth {get; set;} // SmallTeeth Inherits from Teeth
}