Miałem nadzieję zrobić coś takiego, ale wydaje się to nielegalne w C #:
public Collection MethodThatFetchesSomething<T>()
where T : SomeBaseClass
{
return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}
Pojawia się błąd kompilacji: „„ T ”to„ parametr typu ”, który nie jest prawidłowy w danym kontekście”.
Biorąc pod uwagę parametr typu ogólnego, w jaki sposób mogę wywołać metodę statyczną w klasie ogólnej? Metoda statyczna musi być dostępna, biorąc pod uwagę ograniczenie.
Odpowiedzi:
W takim przypadku należy bezpośrednio wywołać metodę statyczną na typie z ograniczeniami. C # (i CLR) nie obsługują wirtualnych metod statycznych. Więc:
... nie może różnić się od:
Przechodzenie przez parametr typu ogólnego jest niepotrzebnym kierunkiem i dlatego nie jest obsługiwane.
źródło
return SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection();
zadziała? Jeśli tak, możesz dodać to do swojej odpowiedzi. Dzięki. U mnie to zadziałało. W moim przypadku moja klasa miała parametr typu, więc tak zrobiłemreturn SomeBaseClass<T>.StaticMethodOnSomeBaseClassThatReturnsCollection();
i to zadziałało.Aby rozwinąć poprzednią odpowiedź, myślę, że refleksja jest bliższa temu, czego chcesz tutaj. Mógłbym podać 1001 powodów, dla których powinieneś lub nie powinieneś coś robić, po prostu odpowiem na twoje pytanie. Myślę, że powinieneś wywołać metodę GetMethod na typie parametru generycznego i przejść stamtąd. Na przykład dla funkcji:
Gdzie T to dowolna klasa, która ma statyczną metodę fetchAll ().
Tak, zdaję sobie sprawę, że jest to przerażająco wolne i może się zawiesić, jeśli someParent nie zmusi wszystkich swoich klas podrzędnych do implementacji funkcji fetchAll, ale odpowiada na zadane pytanie.
źródło
Jedynym sposobem wywołania takiej metody byłaby refleksja, jednak wygląda na to, że możliwe jest zawinięcie tej funkcji w interfejs i użycie wzorca IoC / factory / etc opartego na instancji.
źródło
Wygląda na to, że próbujesz użyć typów ogólnych, aby obejść fakt, że w języku C # nie ma „wirtualnych metod statycznych”.
Niestety to nie zadziała.
źródło
Na razie nie możesz. Potrzebujesz sposobu, aby powiedzieć kompilatorowi, że T ma tę metodę, a obecnie nie ma sposobu, aby to zrobić. (Wielu naciska na Microsoft, aby rozszerzył to, co można określić w ogólnym ograniczeniu, więc być może będzie to możliwe w przyszłości).
źródło
Tutaj zamieszczam przykład, który działa, to obejście
źródło
public T : SomeBaseClass
znaczy?Chciałem tylko wyrzucić, że czasami delegaci rozwiązują te problemy, w zależności od kontekstu.
Jeśli chcesz wywołać metodę statyczną jako rodzaj fabryki lub metody inicjującej, możesz zadeklarować delegata i przekazać metodę statyczną do odpowiedniej fabryki generycznej lub cokolwiek innego, co wymaga tej „klasy ogólnej z tą metodą statyczną”.
Na przykład:
Niestety nie możesz wymusić, że klasa ma właściwą metodę, ale możesz przynajmniej wymusić w czasie kompilacji, że wynikowa metoda fabryczna ma wszystko, czego oczekuje (tj. Metodę inicjalizacji z dokładnie odpowiednim podpisem). Jest to lepsze niż wyjątek odbicia w czasie wykonywania.
Takie podejście ma również pewne zalety, np. Możesz ponownie użyć metod init, ustawić je jako metody instancji itp.
źródło
Powinieneś być w stanie to zrobić za pomocą refleksji, jak opisano tutajPonieważ link nie działa, znalazłem odpowiednie szczegóły w maszynie zwrotnej:
źródło