2015-06-03 23 views
7

Używam poniższego kodu. Jest przeznaczony dla określonego typu, aby je ograniczyć to popup-ności w intellisense itpMetoda rozszerzenia dla dokładnie dwóch różnych typów

public static Generic Get<Generic>(this Entity input) 
{ 
    return (Generic)input; 
} 

Teraz chciałbym korzystać z tego samego Get metody dla innego typu (lub być w pełni pokryte, kilka inny typy, ale wciąż stała liczba). Dlatego dodałem drugą metodę, a kod wygląda następująco.

public static Generic Get<Generic>(this Entity input) 
{ 
    return (Generic)input; 
} 

public static Generic Get<Generic>(this Entity2 input) 
{ 
    return (Generic)input; 
} 

Wydaje mi się, że lepszym rozwiązaniem byłoby, aby utrzymać go w tym samym ciele metody i nadal obejmować wszystkie uznane typy. Czy istnieje składnia do włączenia np. dwa różne typy w podpisie? Coś podobnego do tego pseudo-kod poniżej.

public static Generic Get<Generic>(this [Entity, Entity2] input) 
{ 
    return (Generic)input; 
} 

Najlepszym podejściem mogę myśleć, jak pokazano poniżej, składa się z metody wejścia dla każdego typu i logiki w prywatnym miejscu. Ma sens, gdy logika jest obszerna, ale wygląda na zbędną, gdy jest tylko jedna lub dwie.

public static Generic Get<Generic>(this Entity input) 
{ 
    return CommonLogic(input); 
} 

public static Generic Get<Generic>(this Entity2 input) 
{ 
    return CommonLogic(input); 
} 

private static Generic CommonLogic(Object input) 
{ 
    return (Generic)input; 
} 
+0

Na pewno pójdę z ostatnim podejściem, czy też położę na obiekcie? –

+1

czy jest coś wspólnego między 'Entity' i' Entity2'? –

+6

Czy kontrolujesz źródło zajęć EntityX? Jeśli tak, możesz utworzyć interfejs znacznikowy (pusty) i tylko te klasy implementują interfejs. Następnie wpisz "ten" typ parametru metody rozszerzenia tego interfejsu. – user469104

Odpowiedz

5

C# nie obsługuje notacji [Entity, Entity2], więc ta opcja jest obecnie.

Jeśli Entity i Entity2 akcję wspólnego interfejsu lub klasy bazowej, a następnie zadeklarować ją jako:

public static Generic Get<Generic>(this IEntityCommon input) 
{ 
    return (Generic)input; 
} 

Jeśli nie i utworzeniu Entity, Entity2 etc, a następnie dodać wspólny interfejs. Ten interfejs nie musi definiować żadnych metod i może być pusty, po prostu zapewnia wspólny typ dla metody rozszerzenia.

W przeciwnym razie najlepszym rozwiązaniem jest sposób "CommonLogic".

+0

Notacja była tylko pseudokodem, aby skrócić wyjaśnienie. Klasy nie mają wspólnego dedykowanego im interfejsu, a ponieważ logika jest bardzo krótka, nie ma sensu podejmować wysiłków, by robić wszystko dobrze. Jednak dobrze jest wiedzieć w ogólnym przypadku. –

3

można robić coś takiego

public static TSearch Get<TSource, TSearch>(this TSource obj) where TSource : BaseType, ISomeInterface 
    { 

    } 

T mogą być tylko typu BaseType i wdrażaniu ISomeInterface, ale to nie miałoby to aviable być ograniczona do liczby poprawek obsługiwanych klas

EDIT:

teraz mogą korzystać z tego na obiektach typu BaseType wykonawczych ISomeInterface i Retu W żądanym typie TSearch. Możesz jednak po prostu użyć where TSource : ISomeInterface. Kluczem jest to, że twoje klasy Entity implementują ten interfejs.

Aby dowiedzieć się, jak z niego korzystać, sprawdź numer where - generic type constratint.

+1

Aby to działało, potrzebne są dwa typy ogólne. Wejście i wyjście. W tej chwili zajmuje coś określonego typu i zwraca ten sam typ, który nie jest tym, co robi kod OPs. – juharr

+0

@juharr powinien się zmieścić (Jeśli jego klasy 'Entity' to typeof' BaseType' i 'ISomeInterface') – LuckyLikey

+1

Musisz podać' TSource' jako typ ogólny w metodzie 'public static TSearch Get (ten TSource obj) ' – juharr

Powiązane problemy