2010-04-09 14 views
15

Ok, wiem, że przeciążanie właściwości nie jest obsługiwane w języku C# - większość odnośników wyjaśnia to, powołując się na problem z jedną metodą - odmiennym - zwrotem. Ale co z ustawiaczami? Chciałbym bezpośrednio przypisać wartość jako ciąg lub obiekt, ale tylko zwracać jako ciąg.Przeciążanie właściwości w C#

Jak to:

public string FieldIdList 
    { 
     get { return fieldIdList.ToString(); } 
     set { fieldIdList = new FieldIdList(value); } 
    } 

    public FieldIdList FieldIdList 
    { 
     set { fieldIdList = value; } 
    } 
    private FieldIdList fieldIdList; 

Dlaczego tego nie wolno? Widziałem również, że "właściwości" po prostu tworzą funkcje getter/setter podczas kompilacji. Czy byłoby możliwe stworzenie własnego? Coś takiego:

public void set_FieldIdList(FieldIdList value) 
    { 
     fieldIdList = value; 
    } 

To by zrobić to samo. Myśli?

+1

Byłem ukąszony przez ten sam problem i jestem bardzo rozczarowany tym ograniczeniem tego języka (ponieważ nie widzę powodu). O dziwo, właściwości są fajną opcją języka C#, której brakuje mi w C++, a tam, bardzo ich brakuje. – paercebal

Odpowiedz

7

Właściwości są w istocie parą metod get/set (z których jedna może zostać pominięta), ale sama właściwość ma dodatkowe metadane, co czyni ją właściwością na pierwszym miejscu, a nie tylko dwoma metodami.

Ponieważ podpis właściwości pozostaje niepoprawny, jak w przypadku tylko typu zwracania się, nawet jeśli posiadasz tylko osobę ustawiającą. Jeśli tego potrzebujesz, nie korzystaj z nieruchomości; właściwości związane z ustawieniami nie są ani dobre.

+0

Tak więc kompilator tworzy podpis dla pary metod, a to zapobiega dodatkowym przeciążeniom? Czy to sprawia, że ​​właściwości są wygodniejsze, czy jest ich więcej? Jakie dodatkowe dane sprawiają, że jest to własność? –

+0

Niezupełnie. Tak jak nie możesz mieć dwóch zmiennych innego typu o tej samej nazwie, nie możesz mieć dwóch właściwości o innym typie i tej samej nazwie. Problemy są takie same, kompilator nie będzie wiedział, której zmiennej lub właściwości użyć w danej sytuacji. Dlatego nawet jeśli wybrałeś swoich akcesorów, aby metody get/set nie powodowały konfliktu, kompilator nie może pozwolić ci na wielokrotne używanie tej samej nazwy właściwości, jeśli podpis jest taki sam (pamiętaj, że możesz mieć kilka właściwości indeksujących , ponieważ w tym przypadku podpis różni się, nawet o tej samej nazwie). – Lucero

+3

@Lucero: A jeśli typ właściwości został narzucony przez typ zwrotu metody get? W takim przypadku moglibyśmy mieć settery wielu typów, czyli zbiór metody setowej, która wymaga niezbędnej konwersji.Nie ma zamieszania dla kompilatora i nadal dostajemy silną maszynę, ponieważ wybrana metoda została wybrana zgodnie z zasadami przeciążania metody, zamiast konieczności użycia właściwości 'object' akceptującej cokolwiek w celu rozwiązania problemu (i mojego, jest). – paercebal

1

Jednym ze sposobów (można się spierać, czy jest to dobry wybór, czy nie) jest dodanie drugiej właściwości, która uzyskuje dostęp do danych w innej formie.

Jednak, ponieważ będzie on parsował ciąg znaków (wykonując znaczącą pracę), lepiej nie używać do tego właściwości, ale dodawać metody, które pozwalają uzyskać/ustawić dane w postaci ciągu .

Poszedłbym do fieldIdList zapewniając ToString() i TryParse() interfejsy - wtedy jeśli potrzebujesz tego jako ciąg, nazwałbyś myObject.FieldIdList.ToString() itd. To wszystko hermetyzuje, pozwala na Konwertuj do/z formatów ciągów w dowolnym miejscu kodu, a nie tylko podczas uzyskiwania dostępu do FieldIdLists jako członek innej klasy i sprawia, że ​​kod klienta jest naprawdę jasny i łatwy do zrozumienia.

+1

Przeciążenie 'string' jest przykładem, a nie przypadkiem ogólnym. Pytający chce zapewnić przeciążenie ustalonej metody właściwości, dla typu A i B, niezależnie od ich typów. Powiedzmy, że ich "konwersja" do prawdziwego bazowego typu nieruchomości nie jest "istotną pracą". Wtedy używanie właściwości byłoby dobrym, naturalnym rozwiązaniem w C# IMHO. – paercebal

+0

@paercebal: jako najlepsza praktyka, właściwości powinny mieć trywialne implementacje bez efektów ubocznych - programiści powinni móc traktować właściwość tak, jakby była to prosta zmienna składowa (to znaczy zakładać, że ustawienie będzie szybkie/wydajne, bezstratny, a nie podnosić zdarzeń lub wyjątków). W każdym innym przypadku lepszym sposobem jest zaimplementowanie go jako metody. Przeciążenia własności oznaczają, że właściwość * jest * nietrywialną implementacją i że pewien poziom złożoności jest ukryty. To nie * zawsze * będzie złe, ale często jest. –

+0

Rozumiem wymówkę "najlepszej praktyki", ale jej wymuszenie przez kompilator wydaje się bezużyteczne i przesada, ponieważ: '1. 'źli programiści zawsze piszą złe właściwości, bez względu na to, jak dużo ograniczenia kompilatora dotyczyło' 2.' Ogranicza dobre programistów od robienia czegoś, co byłoby słuszne. . . '3." Czy jestem jedyną osobą, która uznała to za zabawne/sprzeczne z faktem, że nie można przeciążyć właściwości, ale nadal można ją przesłonić (czyniąc ją "wirtualną")? – paercebal

0

Jeśli chcesz móc ustawić właściwość jako ciąg lub obiekt, użyjesz obiektu jako typu właściwości, ponieważ jest to klasa podstawowa (możesz przekazać ciąg do właściwości, która akceptuje obiekt). Nie wydaje się to szczególnie dobrą decyzją projektową, ale można to zrobić. Być może musisz wyjaśnić dalej, co próbujesz osiągnąć?

+3

Pytający był całkiem jasny: ** Chce zapewnić przeciążenia metody dla ustawionej metody. ** Jest to zgodne z prawem, jak pisanie wielu przeciążonych metod 'SetField (Field field)' i 'SetField (string field)'. – paercebal

+0

@DanDiplo Używanie obiektu nie jest pomocne, ponieważ OP chce akceptować tylko dwa typy, String i niestandardową FieldIdList. – Marcel