Can you group common objects into a list?
I have created a machine that converts cookies from one type to another.
Every BiscuitTransformer has a method like DigestiveBiscuitTransformer:
IBiscuit Transform(DigestiveBiscuit digestiveBiscuit)
...
Is it possible to group them using a common interface, given that the type will be different in each transformer, for example. ChocolateBiscuitTransformer
IBiscuit Transform(ChocolateBiscuit chocolateBiscuit)
GingerNutBiscuitTransformer:
IBiscuit Transform(GingerNutBiscuit gingerNutBiscuit)
Ideally, what I'm trying to achieve is the BiscuitTransformationManager, which will take any type of cookie and give you an IBiscuit.
It will load all the transformers into List<IBiscuitTransformer>
and then IBiscuitTransformer exposes as well Type InputBiscuitType {get;}
so you can compare it to your incoming biscuit type:
BiscuitTransformationManager:
IBiscuit Transform<T>(T biscuit)
{
var transformer = LoadTransformers().Single(c => c.InputBiscuitType == typeof(T));
return transformer.Transform(biscuit);
}
I don't think this works because the Transformer will expect a specific type and not T.
The problem is I can't figure out how to group them, and if I create an interface method Transform<T>
I'm not sure how to implement it because T will always be DigestiveBiscuit
in DigestiveBiscuitTransformer
but the code will accept anything that doesn't make sense.
Any ideas?
source to share
I don't think you need generics here.
How simple it is:
IBiscuit Transform(IBiscuit biscuit)
{
var transformer = LoadTransformers().Single(c => c.InputBiscuitType == biscuit.GetType());
return transformer.Transform(biscuit);
}
But of course this means that each of your transformers should have method signatures instead of being type specific, which is the right way in my opinion.
So instead of
IBiscuit Transform(DigestiveBiscuit digestiveBiscuit)
Change this transformer signature (and others) to:
IBiscuit Transform(IBiscuit digestiveBiscuit)
I think this design is cleaner and simpler than trying to make it work with generics.
source to share
I think you can group all the cookie types to convert it to BiscuitTransformManager
.
public interface ITransformedBiscuit {}
public class DigestiveBiscuit : ITransformedBiscuit {}
public class ChocolateBiscuit : ITransformedBiscuit {}
public class BiscuitTransformManager
{
IBiscuit Transform(ITransformedBiscuit biscuit)
{
// Use a reflection in here
var instances = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(ITransformedBiscuit).IsAssignableFrom(t)
&& t.GetConstructor(Type.EmptyTypes) != null
select Activator.CreateInstance(t) as ITransformedBiscuit;
foreach (var instance in instances)
{
instance.Transform(biscuit)
}
}
}
source to share