2009-08-26 21 views
12

Kilka dni temu musiałem przełączyć bool, i skończyło się robi tak:Modyfikuj ValueType z metody rozszerzenia?

IsVisible = !IsVisible; 

Okazało się, że będzie to najprostszy sposób archiwizacji że functionaily. Ale zanim zrobiłem jak powyżej przykład, wypróbowałem na kilka różnych sposobów.

Głównie na temat korzystania z metody rozszerzenia. Co w moim opini sprawiłoby, że byłoby jeszcze prostsze, lub przynajmniej mniej znaków do napisania.

IsVisible.toggle(); 

Ale jako logiczną jest rodzajem wartość, tym bool, który jest wysyłany choć metody wydłużania jest kopią oryginalnego bool, a nie rodzaj odniesienia.

public static void Toggle(this boolean value) 
{ 
value = !value; 
} 

Który zrobi to, co potrzebne, ale jako logiczną coraz przełączanych jest kopią oryginalnego logiczną isnt zmiana stosowanej do oryginału ..

Próbowałem oddanie ref Infront słowo kluczowe „boolean ", ale to się nie skompilowało. I nadal nie znalazłem powodu, dla którego nie kompilowałem, czy nie byłaby to doskonała funkcjonalność dla metod rozszerzeń?

public static void Toggle(this ref boolean value) 

Próbowałem nawet odlewania logiczną do obiektu, który w głowie by uczynić go do typu odniesienia, a potem to już nie być kopią, a zmiana ta przejdzie z powrotem. To też nie działa.

Moje pytanie brzmi, czy możliwe jest wprowadzenie zmian w przedłużeniu, czy w inny sposób, aby uczynić go jeszcze prostszym, niż już jest?

wiem, że to całkiem możliwe, nie będzie żadnych prostszy lub bardziej logiczne niż górna przykład, ale nigdy nie wiadomo :)

Z góry dzięki.

+1

Ułóż to tak proste, jak to możliwe, ale nie prostsze. -Einstein –

+0

btw, metody rozszerzenia muszą być statyczne. Domyślam się, że są w twoim kodzie, po prostu zapomniałeś, żeby były statyczne tutaj – abatishchev

+0

Tak, mój błąd :) – Moulde

Odpowiedz

10

Rodzaje prymitywów są niezmienne. Będziesz musiał napisać swój kod wywoławczy w ten sposób:

IsVisible = IsVisible.Toggle(); 

To najlepsze, co możesz zrobić dzięki metodom rozszerzającym. Nie ma możliwości obejścia tego.

+0

maybe IsVisible = Boolean.Toggle()? – abatishchev

+2

Nie - w jaki sposób "Boolean" jako typ wiedział o stanie zawierał instancję "IsVisible"? Prawe wyrażenie _must_ zawiera gdzieś zmienną. –

+1

Struktury są typami wartości, ale niestety domyślnie nie są one niezmienne. –

1

na marginesie: czy metoda rozszerzenia nie byłaby niewiarygodnie obciążająca dla czegoś tak prostego jak przełączanie bool?

+0

Tak, to by było. To nie jest kombinacja kilku kroków, ale prowadzi to do uniknięcia używania wbudowanego operatora. Staram się trzymać idiomatycznie rozsądnego kodu i staram się unikać pisania DSL (dopóki nie ma sensu). – 48klocs

+0

To okropny przykład, a kod źródłowy był w rzeczywistości kodem, który mnie zainteresował. Tak, bez wymówki. – Moulde

1

W vb.net, metody rozszerzeń mogą zostać zadeklarowane, aby zaakceptować domniemane "to" jako parametr ByRef (odpowiednik ref w języku C#). Takie metody działają tak, jak można by oczekiwać, ale niefortunny fakt, że wywołanie takiej metody rozszerzenia na czymś innym niż zmienna lokalizacja pamięci (np. Na wartości właściwości, tylko do odczytu, lokalizacja pamięci itp.) Spowoduje, że kompilator po cichu przekaże odniesienie do kopię parametru, zamiast wydawania błędu kompilacji [zachowanie głupie, biorąc pod uwagę, że 90% czasu całego parametru punkt używania parametru ref byłoby możliwe do zmodyfikowania go w miejscu wywołania]. Niestety, podczas gdy C# jest generalnie zdolny do używania metod rozszerzeń zapisanych w vb, nie zezwoli na przekazanie parametrów ref bez słowa kluczowego ref i nie zapewnia legalnego sposobu określania ref, z wyjątkiem sytuacji, gdy używa się składni static-function-call.

Powiązane problemy