Consider a bird:
public interface IBird
{
}
public class Duck : IBird
{
public string DuckyProperty { get; set; } //this property is Duck specific!
}
And a bird processor:
public interface IBirdProcessor<out T> where T : IBird
{
double GetBirdWeight(T obj); //this does not compile
}
public class DuckProcessor : IBirdProcessor<Duck>
{
public double GetBirdWeight(Duck duck)
{
return double.Parse(duck.DuckyProperty);
}
}
And a factory to get a bird processor:
public class BirdProcessorFactory
{
public IBirdProcessor<T> GetBirdProcessor<T>(T obj) where T : IBird
{
return (IBirdProcessor<T>)new DuckProcessor();
}
}
Startup:
static void Main()
{
var bird = new Duck() { DuckyProperty = "23" } as IBird; //the cast is necessary to simulate a real world scenario
var factory = new BirdProcessorFactory();
var provider = factory.GetBirdProcessor(bird);
var weight = provider.GetBirdWeight(bird);
}
I want to have an abstract generic bird factory but I get the following error instead:
The type parameter 'T' must be contravariantly valid on 'Program.IBirdProcessor<T>.GetBirdWeight(T)'. 'T' is covariant
If I remove 'out' keyword then I get:
System.InvalidCastException: 'Unable to cast object of type 'DuckProcessor' to type 'IBirdProcessor`1[NotVegetables.Program+IBird]'.'
The cast won't work!
As a workaround I can do this:
public class DuckProcessor : IBirdProcessor<IBird>
{
public double GetBirdWeight(IBird bird)
{
var duck = bird as Duck;
return double.Parse(duck.DuckyProperty);
}
}
But this defies usage of generics at all, I feel like DuckProcessor should work with ducks, not with abstract birds.
Am I doing something completely wrong?
