2012-10-19 11 views
6

Wykonujemy wiele implementacji INotifyPropertyChanged w naszych modelach widoków i, szczerze mówiąc, zmęczyliśmy się koniecznością wywoływania zmian właściwości zdarzeń jawnie w naszym kodzie zarówno ze względu na niedogodności, jak i ze względów estetycznych.Dodanie metody rozszerzenia do składnika Dostęp do właściwości

chcę umieścić rozszerzenie na seter naszej własności, dzięki czemu wynikowy wygląd kodu takich jak:

public string LazyAccessor 
{ 
    get; 
    set.notify(); 
} 

Czy istnieje sposób, aby to zrobić? Czy możemy wymyślić jeden, jeśli nie ma?

Odpowiedz

3

Extension methods można dodać tylko do typów. Moduły pobierające i ustawiające na właściwościach automatycznych są konwertowane na metod przy pomocy zmiennych zapasowych przez kompilator, więc nie ma możliwości umieszczenia na nich metody rozszerzenia.

2

Czy istnieje sposób, aby to zrobić?

Nie, nie ma, nie tak jak wysłałeś. Metody rozszerzeń działają na typów, nie pobierają ani ustawiają.

Czy możemy wymyślić jeden, jeśli nie ma?

Wymagałoby to zmian w specyfikacji C# - nie jest to prawdopodobne.

Istnieją inne metody, które można zastosować, aby to ułatwić - za pomocą klasy bazowej z metodą, która sprawi, że płyta kotła będzie na przykład dzwonić do Ciebie.

+0

Kolejne interesujące podejście. Czy możesz spojrzeć na moją odpowiedź i zobaczyć, czy to też jest możliwe? Cenię twoją opinię, gdy twoja reputacja cię wyprzedza. Może to zbyt ciężkie? –

0

Nie wprowadzono ich do wersji 4.0, ale podobno są one uwzględniane w wersji 5.0.

Znalazłem this podejście pomocne.

4

Zapoznaj się z NotifyPropertyWeaver. Spowoduje to modyfikację kodu w trakcie procesu kompilacji, aby mieć właściwości implementujące wzór INotifyPropertyChanged.

ta jest dostępna jako Visual Studio Extension

+0

Rozumiem, że był to albo prekursor AOP z takimi rzeczami, jak PostSharp, czy też nie znali PostSharp? –

+0

@BigM Nie jestem pewien co do szczegółów tego, jak działają. Wiem, że obaj używają IL Weaving, więc są podobni w swojej koncepcji. Powodem, dla którego używam NotifyPropertyWeaver, jest to, że nie musisz zaśmiecać kodu atrybutami. – cadrell0

+0

Dobry powód, aby używać tego rozwiązania. PostSharp jest *** bardzo *** ogólny i jest odpowiedni do rozwiązania ** jednego punktu bólu, z pewnością będzie bardziej zwięzły! –

0

Nie można tego zrobić na samym zestawie. To jest działanie. Możecie jednak być w stanie to zrobić:

public static class extensions() 
{ 
    public static NotifyAccessorSet(this string value) { some code } 
} 

public class SomeClass() 
{ 
    ..... 
    private string mAccessor; 

    public string LazyAccessor{ 
    get { return mAccessor; } 
    set { mAccessor = value; mAccessor.NotifyAccessorSet(); } 
    } 

} 

To nieco na czubku głowy i pamiętać, że metoda rozszerzenie miałby zastosowanie do wszystkich typów ciąg więc warto wdrożyć swój własny typ zwracany i zastosowanie metoda rozszerzenia do niego. Zwróć ten typ następnie z lazyaccessor.

+0

Nie jestem pewien, ale myślę, aby uruchomić NotifyPropertyEvent, musisz znać obiekt początkowy (nadawca) i nazwę właściwości ("LazyAccessor" w tym przykładzie). Twój kod sprawi, że będzie on jeszcze bardziej rozmowny. – Ondra

+0

Będziesz mieć obiekt początkowy ... będzie to "wartość" w funkcji NotifyAccessorSet. W każdym razie ... po prostu sugestia. takie podejście zaimplementowałoby dodatkowe wywołanie funkcji, po prostu zapewniłoby sposób implementacji powiadomienia w ustawionej metodzie. – DRobertE

0

można emulować zachowanie typu "właściwość" bez wywoływania zdarzenia ręcznie przez przesłonięcie operatorów konwersji niestandardowej ogólnej struktury. Oto moje rozwiązanie:

public struct column<TType> 
{ 
    private TType _value; 

    private column(TType value) : this() 
    { 
     _value = value; 
    } 

    private void Set(TType value) 
    { 
     // Implement your custom set-behavior... 
    } 

    private TType Get() 
    { 
     // Implement your custom get-behavior... 
     return _value; 
    } 

    public override string ToString() 
    { 
     return _value.ToString(); 
    } 

    public static implicit operator column<TType>(TType p) 
    { 
     column<TType> column = new column<TType>(p); 
     column.Set(p); 
     return column; 
    } 

    public static implicit operator TType(column<TType> p) 
    { 
     return p.Get(); 
    } 
} 

Ogłaszam struct z ogólnym parametrem uniknąć błędów konwersji. Możesz go użyć tak:

public class Test 
{ 
    public column<int> kKey; 

    public column<float> dMoney; 

    public column<string> cValue; 


    public Test() 
    { 
     kKey = 42; 
     dMoney = 3.1415926f; 
     cValue = "May the force be with you!"; 
    } 
} 

... Wiem, pytanie jest nieaktualne, ale może pomóc komuś w przyszłości.

Powiązane problemy