Как создать список общих экземпляров делегатов? - PullRequest
4 голосов
/ 16 ноября 2011

Я хочу создать коллекцию фабричных методов, которые могут создавать экземпляры различных объектов, тип которых будет известен только во время выполнения.Я могу легко создать делегат для этого:

delegate T InstanceCreator<T>()

, но это дает ошибку компилятора: "не удается разрешить символ T"

Dictionary<string, InstanceCreator<T>> 

, поэтому вместо этого я просто объявляю

Dictionary<string, Delegate>

Я пытался восполнить это отсутствие специфичности типов в методе Add, но столкнулся с той же проблемой.

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

Есть ли лучший способ убедиться, что только InstanceCreator<T> делегатов добавили в мою коллекцию?

Ответы [ 7 ]

1 голос
/ 16 ноября 2011
public void AddFactory(string typeName,InstanceCreator<T> factory)

Откуда приходит T? Вам нужно сделать сам метод универсальным, чтобы это работало:

public void AddFactory<T>(string typeName,InstanceCreator<T> factory)
1 голос
/ 16 ноября 2011

Вы можете сделать AddFactory универсальным методом:

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

Это ограничит возможность добавления только InstanceCreator<T> элементов.

0 голосов
/ 16 ноября 2011

Если вам не нужно иметь 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)];
}

Кроме того, нет необходимости создаватьваши собственные типы делегатов, Func<T> будет работать так же хорошо.

0 голосов
/ 16 ноября 2011

В какой области вы объявляете делегата.

delegate T InstanceCreator<T>()

Если он находится на уровне пространства имен, то T, на который вы там судитесь, и T, который вы используете в своем методе, не совпадают.Объявите делегата в области видимости класса, и он должен работать.

0 голосов
/ 16 ноября 2011

Вам необходимо передать параметр универсального типа через класс или метод.

Я бы предложил использовать стандартный Func универсальный делегат:

Параметр универсального типа класса:

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

Параметр универсального типа метода:

public void AddFactory<T>(string key, Func<T> factory)
{
      // IDictionary<string, Func<T>> factoryCache
      factoryCache.Add(key, factory);
}
0 голосов
/ 16 ноября 2011

попробуй так ....

public void AddFactory<T>(string typeName,InstanceCreator<T> factory) 
0 голосов
/ 16 ноября 2011

Сделать AddFactory универсальным методом:

public void AddFactory<T>(string typeName, InstanceCreator<T> factory) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...