c # Массив ссылок на делегатов

#c# #arrays #delegates #reference

#c# #массивы #делегаты #ссылка

Вопрос:

При обращении к другим классам мы используем делегаты. Во время модульного тестирования мы переопределяем эти значения.

У меня есть класс, который ссылается на более чем 20 других классов, поэтому я подумал, что создам массив делегатов. Если я создам статический массив этих делегатов (см. Код ниже), в нем будут сохранены значения делегатов, а не ссылка на делегата.

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

 private static Func<int, bool> firstMethod = ExternalClass1.Method;
private static Func<int, bool> secondMethod = ExternalClass2.Method;
private static Func<int, bool> thirdMethod = ExternalClass3.Method;

private static Func<int, bool>[] handlers = { first, second, third };

public bool Test(int value)
{
    foreach (var handler in handlers)
    {
        if (handler.Invoke(value) == true)
        {
             return true;
        }
    }

    return false;
}
  

Комментарии:

1. Так в чем проблема? В чем ошибка?

2. Рассматривали ли вы возможность использования интерфейсов вместо делегатов в некоторых случаях?

3. Мы используем CSLA, и поэтому рассматриваемые методы являются статическими. Интерфейс AIUI не может быть реализован статическими методами, поэтому такой подход не является вариантом.

Ответ №1:

Вместо создания этого массива обработчиков вы можете сделать что-то вроде этого:

 private static IEnumerable<Func<int,bool>> GetHandlers()
{
    yield return firstMethod;
    yield return secondMethod;
    yield return thirdMethod;
}
  

Теперь у вас есть способ получить фактические ссылки на поля, чтобы их можно было заменить для модульных тестов, но также есть способ перебирать все обработчики. Тем не менее, массив делегатов, который может быть заменен, в основном представляет собой интерфейс или набор абстрактных методов, которые могут быть переопределены. Это может быть чище и проще в обслуживании, если вы реализуете полиморфизм, используя языковые возможности, предназначенные для его обеспечения. Для удобства замены поведения с использованием делегатов во время ваших модульных тестов вы можете использовать макетные фреймворки, такие как Moq, для макетирования интерфейса без необходимости писать специальные тестовые классы.

-Dan

Комментарии:

1. Спасибо. Похоже, это именно то, что мне нужно.