Я ищу способы улучшить согласованность, краткость и удобочитаемость некоторого кода в приложении, над которым я работаю. Стартовый код выглядел примерно так:C# метод расширения по типу с аргументом общего типа
context.GetGraphType<Bar>().Subscribe<Fizz>(
(instance, evt) => e.Execute((Bar)instance.Instance)
);
Существует несколько идентичных строк кода, как указано выше. Я хотел переписать его выглядеть примерно так:
typeof(Bar).SubscribeTo<Fizz>(context);
С одной стороны, это позволило бы мне воспользоваться формализациями то, что уже стала неформальной конвенцией. Кроме того, я надеялся, что теперь он будет читать что-то вроде «бар, подписывается на событие fizz в данном контексте», а не «контекст получает тип бара и подписывается на fizz, а затем делает некоторые вещи». Я думаю, что поток лучше, и сотрудник, которого я спросил, согласился.
Я начал реализовывать это как метод расширения. Чтобы выполнить вышеизложенное, я хотел использовать абстрактный базовый класс для типа события, поэтому Fizz
будет Event<T>
. Это означало бы, что аргумент родового типа для метода расширения должен быть ограничен типом того типа, к которому вызывается метод расширения. Итак, для приведенного выше примера Fizz
должен быть типа Event<Bar>
.
Возможно ли это? В то же время я пошел с альтернативным решением, но мне все же интересно, если это можно сделать. Другие предложения приветствуются.
Спасибо!
Редактировать # 1: Чтобы быть ясным, я понимаю, что могу использовать дополнительный параметр типа, но я ищу способы избежать этого, если это возможно.
Редактировать # 2: Я думаю, что я собираюсь пойти с небольшим изменением принятого ответа, так как он не соответствует 100% моему сценарию. Суть в том, что общий статический класс можно использовать вместо метода расширения для выполнения моей цели. Спасибо dss539!
Обновить код (может быть опечаток, так как я делаю это на лету):
public class Bar { }
public class Event<TSubscriber>
{
public abstract void Execute(TSubscriber source);
}
public class Fizz : Event<Bar>
{
public override void Execute(Bar bar)
{
// respond to event
}
}
public class Context { }
public static class ForType<TSubscriber>
{
public static void SubscribeTo<TEvent>(Context context)
where TEvent : Event<TSubscriber>
{
context.GetType<TSubscriber>().Subscribe<TEvent>(
(evt, args) => evt.Execute((TSubscriber)args.Source));
}
}
public static void Run()
{
ForType<Bar>.SubscribeTo<Fizz>(context);
}
Я не совсем понимаю ваш вопрос. Как выглядит ваша существующая подпись метода? 'Подписка (этот тип типа, действие )'? Если вы покажете, что у вас есть (или эквивалент), это может помочь объяснить. –
dss539
Я думаю, что у меня была аналогичная проблема с дизайном некоторое время назад. Удачи :) – leppie
@ dss539 Это будет больше похоже на подписку (этот тип типа, контекст ctx). Проблема в том, что нет способа (что я знаю), чтобы ограничить T типом Event . –