Przeglądając jakiś kod, zauważyłem możliwość jego zmiany w celu użycia generycznych. Kod (zaciemniony) wygląda następująco:
public void DoAllTheThings(Type typeOfTarget, object[] possibleTargets)
{
var someProperty = typeOfTarget.GetProperty(possibleTargets[0]);
...
}
Ten kod można zastąpić ogólnymi, takimi jak:
public void DoAllTheThings<T>(object[] possibleTargets[0])
{
var someProperty = type(T).getProperty(possibleTargets[0]);
...
}
Badając zalety i wady tego podejścia, znalazłem termin zwany nadużyciem ogólnym . Widzieć:
- Ochrona niewtajemniczonych (programistów) przed lekami generycznymi
- https://stackoverflow.com/questions/28203199/is-this-an-abuse-of-generics
- https://codereview.stackexchange.com/q/60695
Moje pytanie składa się z dwóch części:
- Czy są jakieś korzyści z przejścia na takie leki generyczne? (Wydajność? Czytelność?)
- Co to jest nadużycie generyczne? I czy używanie generycznych za każdym razem, gdy występuje parametr typu, stanowi nadużycie ?
Odpowiedzi:
Kiedy odpowiednio zastosowane są ogólne, usuwają kod zamiast po prostu go porządkuje. Przede wszystkim kodem, który generycy najlepiej usuwają, jest rzutowanie czcionek, odbicie i pisanie dynamiczne. Dlatego nadużycie generyczne można luźno zdefiniować jako tworzenie kodu ogólnego bez znacznego ograniczenia rzutowania, refleksji lub dynamicznego pisania w porównaniu z implementacją nie ogólną.
W odniesieniu do swojej przykład spodziewałbym odpowiednie stosowanie leków generycznych zmianę
object[]
DoT[]
lub podobny i uniknąćType
lubtype
całkowicie. Może to wymagać znacznego refaktoryzacji w innym miejscu, ale jeśli w tym przypadku właściwe jest użycie ogólnych, powinno to być prostsze, kiedy skończysz.źródło
object[]
naT[]
.Użyłbym zasady non-nonsense: Generics, podobnie jak wszystkie inne konstrukcje programistyczne, istnieją, aby rozwiązać problem . Jeśli nie ma problemu do rozwiązania dla leków generycznych, użycie ich jest nadużyciem.
W konkretnym przypadku ogólnych, istnieją one głównie w celu oderwania się od konkretnych typów, umożliwiając złożenie implementacji kodu dla różnych typów w jeden ogólny szablon (lub jakkolwiek inny język to nazwie). Załóżmy, że masz kod, który używa typu
Foo
. Możesz zamienić ten typ na ogólnyT
, ale jeśli tylko potrzebujesz tego kodu do pracyFoo
, po prostu nie ma innego kodu, za pomocą którego można go złożyć razem. W związku z tym nie ma problemu do rozwiązania, więc pośrednie dodanie nazwy ogólnej służyłoby po prostu zmniejszeniu czytelności.W związku z tym sugerowałbym po prostu napisanie kodu bez użycia ogólnych, dopóki nie zobaczysz potrzeby ich wprowadzenia (ponieważ potrzebujesz drugiej instancji). Wtedy, i tylko wtedy, nadszedł czas na refaktoryzację kodu w celu użycia generycznych. Każde użycie przed tym punktem jest nadużyciem w moich oczach.
Brzmi to trochę zbyt pedantycznie, więc przypominam:
nie ma reguły bez wyjątków w programowaniu. Ta zasada obejmuje.
źródło
Kod wygląda dziwnie. Ale jeśli go nazywamy, ładniej jest określić typ jako ogólny.
https://stackoverflow.com/questions/10955579/passing-just-a-type-as-a-parameter-in-c-sharp
Osobiście nie lubię tych zniekształceń, które sprawiają, że kod wywoławczy wygląda ładnie. na przykład cała „płynna” rzecz i metody rozszerzenia.
Ale musisz przyznać, że ma popularnych zwolenników. nawet Microsoft używa go na przykład w jedności
źródło
Dla mnie wygląda to tak, jakbyś był na dobrej drodze, ale nie dokończył pracy.
Czy rozważałeś zmianę
object[]
parametruFunc<T,object>[]
na następny krok?źródło