Сохранить статическую ссылку на метод экземпляра? - PullRequest
1 голос
/ 10 августа 2011

Я хотел бы создать статический массив, содержащий делегаты. Я буду использовать этот массив для поиска нужного мне делегата. Например:

class HandlerID
{
    public int ID { get; set; }
    public Func<int, bool> Handler { get; set; }
}

protected const HandlerID[] HandlerIDs = {
    new SectionRenderer() { ID = SectionTypes.Type1, Handler = MyType1Handler },
    new SectionRenderer() { ID = SectionTypes.Type2, Handler = MyType2Handler },
    // Etc.
}

protected bool MyType1Handler(int arg)
{
    return false;
}

// Etc.

Однако присвоение Handler в массиве HandlerID приводит к следующей ошибке:

Ссылка на объект требуется для нестатического поля, метода или свойства 'MyType1Handler (int)'

Я бы предпочел, чтобы массив был const, поэтому его не нужно инициализировать для каждого экземпляра моего класса. Есть ли способ сохранить метод экземпляра в статическом массиве?

Ответы [ 3 ]

5 голосов
/ 10 августа 2011

Это не имеет смысла.
Когда вы вызываете делегатов в массиве, им нужен экземпляр вашего класса для работы.

Следовательно, вам нужен отдельный набор делегатов для каждого экземпляра класса.

Если методам на самом деле не нужен экземпляр для работы, вы можете сделать их static, что решит проблему.

Кроме того, вы можете взять экземпляр в качестве параметра для делегата и использовать лямбда-выражение, которое вызывает метод: Handler = (instance, arg) => instance.MyType1Handler(arg)

1 голос
/ 10 августа 2011

Вы не можете создать делегата для статической функции, и вы не можете создать делегата для функции в несуществующем экземпляре объекта. Однако вы можете сохранить MethodInfo и позже вызвать его в экземпляре.

 // Use MethodInfo instead of Func in HandlerId
 public MethodInfo Method { get; set; }

 // Create the static list of handlers
 protected static HandlerID[] HandlerIDs = {    
  new SectionRenderer() { ID = SectionTypes.Type1, Method = typeof(MyHandlersClass).GetMethod("MyType1Handler") },    
  new SectionRenderer() { ID = SectionTypes.Type2, Method = typeof(MyHandlersClass).GetMethod("MyType2Handler") },    
   // Etc.
  }

  // invoke at some point
  HandlersIds[0].Method.Invoke(aninstanceobject, new object[] { arg } );
1 голос
/ 10 августа 2011

Вы не можете объявить массив const в C #, попробуйте readonly, который гарантирует, что указатель на массив (экземпляр) не изменится, но, насколько я знаю, нет способа декларативно предотвратить изменение элементов .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...