Reputation: 28158
I have a factory defined like so :
public IPopulator CreatePopulator<T>(ReportItem Item) where T : IReportElement
{
if (typeof(T) == typeof(BarChartElement))
{
return BarChartPopulator.Create(Item);
}
else
{
throw new NotSupportedException(string.Format("Type: {0} is not suppported by {1}", typeof(T).Name, this.GetType().Name));
}
}
In the class that calls this method I have a variable like this:
IReportElement MyElement { get; set; }
Assuming MyElement is instantiated to a type that implements IReportElement, How can I call my factory using this variable ?
I have tried
Type VariableType = MyChartElement.GetType();
PopulatorFactory.CreatePopulator<VariableType>(new Chart());
And
PopulatorFactory.CreatePopulator<MyVariable.GetType()>(new Chart());
I could write a switch statement but I feel like there should be some way for me to pass my type. Is this possible ?
Upvotes: 0
Views: 3127
Reputation: 27913
If you are working with a library that cannot change to be like @Dan Bryant suggested, something like this ought to work.
typeof (PopulatorFactory)
.GetMethod("CreatePopulator")
.GetGenericMethodDefinition()
.MakeGenericMethod(new[] {myVariable.GetType()})
.Invoke(null, new object []{new Chart ()});
Upvotes: 2
Reputation: 124642
You can't use variables as generic arguments like that. The only way they can provide type safety is if the type is known at compile time.
Factory methods as you describe to tend to be implemented as switch statements, and there is nothing inherently wrong with that. You can pass an enumerated type to your factory method which will in turn return an instance of a type that implements IReportElement.
I don't quite get what you are trying to accomplish here anyway. Your generic factory method is checking the type of the argument. If you have to check the type then, well, it ain't generic anymore, so what's the point?
Perhaps you could go into a bit more depth as to what problem you are actually trying to solve with this code. There may be a better alternative that you have not yet considered.
Upvotes: 3