简体   繁体   English

如何创建通用委托实例列表?

[英]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" 但这会导致编译器错误:“无法解析符号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. 我试图弥补Add方法中类型特殊性的不足,但是遇到了同样的问题。

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? 有没有更好的方法来确保仅将InstanceCreator<T>委托添加到我的集合中?

You can make AddFactory a generic method: 您可以将AddFactory设为通用方法:

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

This will constrain it to only allowing InstanceCreator<T> elements to be added. 这将限制它仅允许添加InstanceCreator<T>元素。

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

Where is T coming from? T从哪里来? You need to make the method itself generic for this to work: 您需要使方法本身通用,以使其起作用:

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

使AddFactory成为通用方法:

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

尝试这样...

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

You need to pass generic type parameter through the class or method. 您需要通过类或方法传递通用类型参数。

I would suggest using standard Func< TResult > generic delegate: 我建议使用标准的Func <TResult>泛型委托:

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);
}

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. 如果它在名称空间级别,则您在那里使用的T与您在方法中使用的T不相同。 Declare the delegate in the scope of the class and it should work. 在类的范围内声明该委托,它应该可以工作。

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: 如果您不需要将typeName作为字符串,则建议使用Dictionary<Type, Delegate>并使用如下所示的内容:

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. 另外,不需要创建自己的委托类型, Func<T>也可以正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM