Reputation: 121
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
Reputation: 43046
Make AddFactory
a generic method:
public void AddFactory<T>(string typeName, InstanceCreator<T> factory)
Upvotes: 0
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
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
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
Reputation: 17701
try like this....
public void AddFactory<T>(string typeName,InstanceCreator<T> factory)
Upvotes: 0
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
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