Steve Hunt
Steve Hunt

Reputation: 121

How do I create a list of generic delegate instances?

I want to create a collection of factory methods that can instantiate various objects, whose type will only be known at run time. I can easily create a delegate for this:

delegate T InstanceCreator<T>()

but this gives a compiler error: "cannot resolve symbol T"

Dictionary<string, InstanceCreator<T>> 

so in place of this I just declare

Dictionary<string, Delegate>

I tried to make up for this lack of type specificity in the Add method but run into the same problem.

public void AddFactory(string typeName, InstanceCreator<T> factory)

Is there a better way to to ensure that only InstanceCreator<T> delegates get added to my collection?

Upvotes: 4

Views: 377

Answers (7)

phoog
phoog

Reputation: 43046

Make AddFactory a generic method:

public void AddFactory<T>(string typeName, InstanceCreator<T> factory) 

Upvotes: 0

sll
sll

Reputation: 62514

You need to pass generic type parameter through the class or method.

I would suggest using standard Func< TResult > generic delegate:

Class generic type parameter:

public class FactoryRepository<T>
{
  IDictionary<string, Func<T>> factoryCache;

  public FactoryRepository()
  {
      this.factoryCache = new Dictionary<string, Func<T>>();
  }

  public void AddFactory(string key, Func<T> factory)
  {   
      this.factoryCache.Add(key, factory);
  }
}

Method generic type parameter:

public void AddFactory<T>(string key, Func<T> factory)
{
      // IDictionary<string, Func<T>> factoryCache
      factoryCache.Add(key, factory);
}

Upvotes: 0

svick
svick

Reputation: 244837

If you don't need to have typeName as a string, I would suggest having a Dictionary<Type, Delegate> and use it something like this:

Dictionary<Type, Delegate> factories = new Dictionary<Type, Delegate>();

public void AddFactory<T>(InstanceCreator<T> factory)
{
    factories.Add(typeof(T), factory);
}

public InstanceCreator<T> GetFactory()
{
   return (InstanceCreator<T>)factories[typeof(T)];
}

Also, there is no need to create your own delegate types, Func<T> would work just as well.

Upvotes: 0

ClassicThunder
ClassicThunder

Reputation: 1936

At what scope are you declaring the delegate.

delegate T InstanceCreator<T>()

If its at the namespace level the T you are suing there and T you are using in your method are not the same. Declare the delegate in the scope of the class and it should work.

Upvotes: 0

Glory Raj
Glory Raj

Reputation: 17701

try like this....

public void AddFactory<T>(string typeName,InstanceCreator<T> factory) 

Upvotes: 0

Ed Swangren
Ed Swangren

Reputation: 124692

public void AddFactory(string typeName,InstanceCreator<T> factory)

Where is T coming from? You need to make the method itself generic for this to work:

public void AddFactory<T>(string typeName,InstanceCreator<T> factory)

Upvotes: 1

Reed Copsey
Reed Copsey

Reputation: 564441

You can make AddFactory a generic method:

public void AddFactory<T>(string typeName, InstanceCreator<T> factory)

This will constrain it to only allowing InstanceCreator<T> elements to be added.

Upvotes: 1

Related Questions