Szukam sposobów na poprawę spójności, zwięzłości i czytelności kodu w aplikacji, nad którą pracuję. Kod począwszy wyglądał mniej więcej tak:Metoda rozszerzenia C# na typie z argumentem typu ogólnego
context.GetGraphType<Bar>().Subscribe<Fizz>(
(instance, evt) => e.Execute((Bar)instance.Instance)
);
Istnieje wiele prawie identycznych linii kodu jak wyżej. Chciałem przepisać to wyglądać mniej więcej tak:
typeof(Bar).SubscribeTo<Fizz>(context);
Z jednej strony, to pozwoli mi skorzystać z sformalizowania, co już stało się nieformalna konwencja. Miałem także nadzieję, że teraz będzie czytać coś w stylu "bar subskrybuje wydarzenie fizz w danym kontekście", a nie "kontekst pobiera typ paska i subskrybuje fizz, a następnie robi kilka rzeczy." Myślę, że przepływ jest lepiej, a współpracownik, którego o to pytałem, zgodził się.
Zacząłem wdrażać to jako metodę rozszerzenia. W celu osiągnięcia powyższego chciałem użyć abstrakcyjnej ogólnej klasy bazowej dla typu zdarzenia, więcbyłby Event<T>
. Oznaczałoby to, że ogólny typ argumentu metody rozszerzenia musiałby być ograniczony do typu, do którego wywoływana jest metoda rozszerzenia. Tak więc w powyższym przykładzie Fizz
musiałby być typu Event<Bar>
.
Czy to możliwe? W międzyczasie wybrałem alternatywne rozwiązanie, ale nadal jestem ciekawy, czy można to osiągnąć. Inne sugestie są również mile widziane.
Dzięki!
Edycja nr 1: Dla jasności zdaję sobie sprawę, że mogę użyć dodatkowego parametru, ale szukam sposobów, aby tego uniknąć, jeśli to możliwe.
Edycja nr 2: Myślę, że zamierzam przejść z niewielką zmianą zaakceptowanej odpowiedzi, ponieważ nie pasuje ona w 100% do mojego scenariusza. Najważniejsze jest to, że zamiast metody rozszerzenia typu można użyć ogólnej klasy statycznej, aby osiągnąć mój cel. Dzięki dss539!
kod Update (nie może być literówki, ponieważ robię to na bieżąco):
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);
}
Nie bardzo rozumiem twoje pytanie. Jak wygląda twój istniejący podpis metody? 'Subskrybuj (ten typ Typ, Działanie )'? Jeśli pokażesz, co masz (lub odpowiednik), to może ci to wyjaśnić. –
dss539
Wydaje mi się, że jakiś czas temu miałem podobne problemy z projektowaniem. Powodzenia :) – leppie
@ dss539 To byłoby bardziej Subskrybuj (ten typ Typ, Kontekst ctx). Problem polega na tym, że nie ma sposobu (o którym wiem), aby ograniczyć T do zdarzenia typu