2015-08-26 10 views
6

Mam kilka klas, które są identyfikowane przez jakiś identyfikator (który jest unikalną liczbą całkowitą dla każdej klasy). Następnie potrzebuję metody, która pobiera liczbę całkowitą (ID) jako argument i zwraca odpowiedni typ klasy. Jak dotąd doszedłem do tego:Metoda C# do zwracania typu

public static Type GetById(int id) 
{ 
    switch (id) 
    { 
     case 1: return (new ClassA()).GetType(); 
     case 2: return (new ClassB()).GetType(); 
     case 3: return (new ClassC()).GetType(); 
     // ... and so on 
    } 
} 

Na razie wydaje się, że to działa, ale z jakiegoś powodu nie podoba mi się, że mam do instancji klasy, aby uzyskać jego typ. Czy to może powodować problemy?

Innym rozwiązaniem znalazłem jest użycie Type.GetType (classNameAsString) metoda, ale myślę, że to może spowodować pewne błędy wykonawcze lub błędów w nazwie klasy sprawa zostanie zmieniona (tj zmienić nazwę klasy, ale zapomniał zaktualizuj metodę GetById).

Czy jest jakiś lepszy sposób na zrobienie tego?

+0

Czy próbujesz stworzyć fabrykę? – Jonesopolis

+0

Niezupełnie, po prostu potrzebuję tego typu, aby dostarczyć go do ogólnej metody w bazowym api. –

Odpowiedz

19

Użyj operatora zamiast

public static Type GetById(int id) 
{ 
    switch (id) 
    { 
     case 1: return typeof(ClassA); 
     case 2: return typeof(ClassB); 
     case 3: return typeof(ClassC); 
     // ... and so on 
    } 
} 

typeof Na marginesie, chciałbym poważnie zakwestionować cały ten projekt - to jest dziwne typy map do liczb całkowitych.

+0

Czy to dziwne? Rozważmy plik konfiguracyjny, gdy do określenia zachowania używa się wyliczenia z wartościami * N *, a zachowanie to zapewnia klasa * N *. Będziesz chciał odwzorować wartość wyliczenia na te typy. – Gusdor

+0

@Gusdor Wydaje mi się, że to nie jest tak daleko idące. Ale nadal będzie to mapować wyliczenie na * instancję * typu, a nie na liczbę całkowitą typu "Typ". – dcastro

+0

Ah, rozumiem twoją rezerwację. W końcu to dziwne! – Gusdor

13

Po prostu nie zadeklaruj słownika ?

private static Dictionary<int, Type> types = new Dictionary<int, Type>() { 
    {1, typeof(ClassA)}, 
    {2, typeof(ClassB)}, 
    {3, typeof(ClassC)}, 
    ... and so on 
    }; 

    public static Type GetById(int id) { 
    Type result = null; 

    if (types.TryGetValue(id, out result)) 
     return result; 

    return null; // or throw exception 
    } 
1

Inną alternatywą byłoby stworzenie enum:

public enum ClassType 
{ 
    ClassA = 1, 
    ClassB = 2, 
    ClassC = 3 
} 

A następnie zmieniając metodę do zaakceptowania tej enum i zwraca typ:

public static Type GetById(ClassType id) 
{ 
    //Will return null if the Type is not found, 
    //Add true as a second parameter to throw if not found 
    return Type.GetType(id.ToString()); 
} 

ten sposób usunie magiczne numery od Twój kod, ale działa tylko tak długo, jak nazwy klas są zgodne z opcjami wyliczania. Spowoduje to, że twój kod będzie znacznie mniejszy, ale jak wskazali inni, powinieneś naprawdę zakwestionować swój projekt aplikacji, ponieważ nie jest to właściwe.

Powiązane problemy