Правило SonarLint S1172 Неиспользуемые параметры метода должны быть удалены, а обработчики событий

Как мне исправить правило SonarLint S1172 «Неиспользуемые параметры метода должны быть удалены» при создании методов EventHandler.

public void Subscribe()
{
    MyEvent += OnMyEvent;
}

public void UnSubscribe()
{
    MyEvent -= OnMyEvent;
}

private void OnMyEvent(object sender, EventArgs e)
{
   DoSomething();
}

Вы можете переписать код с помощью Reactive Extensions и создать «Observables», но это довольно сложное решение для простых обработчиков событий. Другим вариантом может быть переписывание кода, например:

public void Subscribe()
{
   MyEvent += (s,e) => DoSomething();
}

Но тогда вопрос в том, как вы делаете UnSubscribe()? На мой взгляд, неиспользуемые параметры неприменимы к методам обработчика событий. Но это может быть сложно обнаружить в SonarLint.


person Niek Jannink    schedule 18.08.2015    source источник
comment
Как упоминалось ниже, сохранение делегата в поле является опцией. Но я думаю, что мы должны правильно решить эту проблему в SonarLint, если это распространенный сценарий. Я чувствую, что если вам вообще не нужны sender и EventArgs, вы можете использовать собственный делегат, у которого их нет. Но это работает только в том случае, если вы контролируете тип события. Так ли это? У вас есть подписчики, которым нужны эти два параметра? Как вы думаете, это противоречит лучшим практикам обработки событий?   -  person Tamas    schedule 19.08.2015
comment
Я думаю, что это руководство по дизайну, согласно которому события всегда должны быть (производными) типа EventHandler. Это означает, что вы всегда получите отправителя и EventArgs. Таким образом, даже если подписчики не используют эти параметры, все события в среде .Net строятся с использованием этой парадигмы, поэтому SonarLint должен справиться с этим. Я думаю, что resharper правильно распознает методы обработки событий и игнорирует их неиспользуемые параметры.   -  person Niek Jannink    schedule 19.08.2015
comment
Спасибо, давайте продолжим обсуждение на github.com/SonarSource/sonarlint-vs/issues/211.   -  person Tamas    schedule 19.08.2015
comment
Это похоже на C# или VisualStudio feature, но действительно вызывает другие вопросы, см. мой вопрос: stackoverflow.com/q/41162335/1845672 . кстати, ссылка на обсуждение на github мертва   -  person Roland    schedule 15.12.2016


Ответы (1)


Если вам нужно отказаться от подписки, вам нужно сохранить делегат (удалить статический код для правильного кода, он вставлен из проект взломанного консольного приложения):

public static event EventHandler TestEvent;

private static EventHandler saved = (s, e) => DoSomething();

static void Main(string[] args)
{
    TestEvent += saved;
    TestEvent -= saved;
}

internal static void DoSomething()
{
}

Или используйте массовую отмену подписки:

foreach (Delegate d in TestEvent.GetInvocationList())
{
    TestEvent -= (EventHandler)d;
}

Или, если вы являетесь владельцем мероприятия, вы также можете использовать это, чтобы отменить подписку на все:

TestEvent = null;

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

if (sender == null) 
    throw ArgumentNullException(nameof(sender));

чтобы избавиться от предупреждения ;)

person jessehouwing    schedule 18.08.2015
comment
PS: я думаю, что это следует рассматривать как ошибку в S1172. - person jessehouwing; 18.08.2015
comment
Это не решает мою проблему. Необходимость хранить EventHandler в поле для устранения предупреждения о правиле S1172 не кажется правильным способом устранения предупреждения. Так что да, я бы также сказал, что это ошибка в S1172. - person Niek Jannink; 18.08.2015
comment
Просто добавьте ArgumentNullChecks;). Если вы начнете использовать параметры, это будет следующая ошибка SonarLint, с которой вы столкнетесь ;). - person jessehouwing; 18.08.2015
comment
Поднято в проблемах SonarLint на GitHub: github.com/SonarSource/sonarlint-vs/issues /211 - person jessehouwing; 19.08.2015