BentOnCoding
BentOnCoding

Reputation: 28158

How to Dynamically Pass a Type to a Generic Factory?

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

Answers (2)

agent-j
agent-j

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

Ed Swangren
Ed Swangren

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

Related Questions