2009-11-14 14 views
8

Chcę stworzyć prostą funkcję rodzajoweC#: Jak korzystać z metody rodzajowe z „out” zmienna

void Assign<T>(out T result) 
{ 
    Type type = typeof(T); 
    if (type.Name == "String") 
    { 
    // result = "hello"; 
    } 
    else if (type.Name == "Int32") 
    { 
    // result = 100; 
    } 
    else result = default(T); 
} 

Zastosowanie:

int value; 
string text; 

Assign(value); // <<< should set value to 100 
Assign(text); // <<< should set text to "hello" 

Moje pytanie jest jak można zaprogramować kod, aby ustawić te wartości, tj.. brakujące kody w sekcji komentarzy.

Dzięki za pomoc.

Odpowiedz

16

Wygląda na to, że w tym przypadku robisz to, aby uniknąć boksowania? Trudno powiedzieć bez więcej informacji, ale w tym konkretnym przykładzie, że byłoby o wiele łatwiejsze i prawdopodobnie mniej skłonne do błędów po prostu użyć metody przeciążenia:

void Assign(out string value) 
{ 
    //... 
} 

void Assign(out int value) 
{ 
    //... 
} 

Dla celów uczenia się, co konkretnie jest źle tutaj , trzeba zrobić, aby rzucić wartość przedmiotu przed rzucając go do typu rodzajowego:

(T)(object)"hello world!"; 

które IMO jest dość paskudny i powinno być ostatecznością - z pewnością nie czyni Twój kod dowolny czystsze.

Za każdym razem, gdy sprawdzasz typowo parametry ogólne, jest to dobre wskazanie, że generics nie są właściwym rozwiązaniem twojego problemu. Wykonywanie ogólnych sprawdzeń parametrów powoduje, że kod jest bardziej złożony, a nie prostszy. To sprawia, że ​​jedna metoda jest odpowiedzialna za różne zachowania w oparciu o typ, zamiast serii pojedynczych metod, które można łatwo zmienić bez przypadkowego wpływu na inne. Zobacz Single Responsibility Principle.

0

Oto jeden sposób:

static void Assign<T>(out T result) { 
    Type type = typeof(T); 
    if (type.Name == "String") { 
     result = (T)Convert.ChangeType("hello", typeof(T)); 
    } 
    else if (type.Name == "Int32") { 
     result = (T)Convert.ChangeType(100, typeof(T)); 
    } 
    else { 
     result = default(T); 
    } 
} 

Ale to zapachy kodu naprawdę złe i sprzeczne z punktu generycznych (zamiast używać metod przeciążonych). Mam nadzieję, że to nie skończy się gdzieś w kodzie produkcyjnym i jest tylko dla budowania.

+0

Thanks a lot; to działa. Powodem, dla którego stosuję podejście ogólne jest uproszczenie mojego kodu. Ponieważ "przypisanie kodu" jest potrzebne tylko dla określonego typu (np. Ciąg); byłoby źle tworzyć przeciążone funkcje dla wszystkich możliwych typów. result = default (T) // to typowe zachowanie –

+7

Nie zgadzam się z tobą. Myślę, że przeciążanie jest właśnie do tego. Używaj generycznych tylko w razie potrzeby. – Sheldon

3

Po pierwsze, to bardzo zły wzór. Nie powinieneś używać tego rodzaju wzoru. Może jeśli opisasz to, co naprawdę chcesz osiągnąć, będą lepsze odpowiedzi.

Kod poniżej działa, ale jak powiedziałem, pisanie kodu w ten sposób jest złym pomysłem.

void Assign<T>(out T result) 
    { 
     Type type = typeof(T); 
     if (type.Name == "String") 
     { result = (T) ((object)"hello"); } 
     else if (type.Name == "Int32") 
     { result = (T) ((object)100); } 
     else result = default(T); 
    } 

i użytkowania:

 int value; 
     string text; 

     Assign(out value); 
     Assign(out text); 
1
public T GetObject<T>(string val) 
{ 
    T _object = default(T); 
    _object = (T)Convert.ChangeType(val, typeof(T)); 
    return _object; 
} 
Powiązane problemy