Piszę aplikację internetową .NET, w której administratorzy mogą dostosowywać różne formularze wprowadzania danych do swoich użytkowników. Istnieje około pół tuzina różnych typów pól, które administratorzy mogą tworzyć i dostosowywać (np. Tekst, numer, rozwijanie, przesyłanie plików). Wszystkie pola mają zestaw podstawowych atrybutów/zachowań (czy wymagane jest pole? Czy będzie mieć domyślną wartość pola?). Istnieje również szereg specyficznych dla danego pola atrybutów/zachowań (np. Lista rozwijana ma atrybut źródła danych, ale pole tekstowe nie). W celu uproszczenia pozostawiam wiele innych cech domeny problemowej.Metoda przeciążania i polimorfizm
Hierarchia klas jest prosta: abstrakcyjna nadklasa, która zawiera w sobie typowe zachowania/atrybuty oraz około pół tuzina konkretnych podklas zajmujących się konkretnymi tematami.
Każdy typ pola jest renderowany (tzn. Mapowany) jako określony typ formantu serwera .NET, który wywodzi się z System.Web.UI.Control.
stworzyłem następujący kod do mapowania wartości między obiektów domeny pola i odpowiadających im kontroli UI:
public static void Bind(Control control, IList<DocumentFieldBase> fieldBaseList)
foreach (DocumentFieldBase fieldBase in fields){
if (typeof (DocumentFieldText).IsInstanceOfType(fieldBase)){
TextBox textbox = (TextBox) control;
textbox.Text = (fieldBase as DocumentFieldText).GetValue();
}
if (typeof (DocumentFieldDropDown).IsInstanceOfType(fieldBase)){
DropDown dropDown= (DropDown) control;
dropDown.Text = (fieldBase as DocumentFieldSelectOne).GetValue().Text;
dropDown.DataSource= (fieldBase as DocumentFieldSelectOne).DataSource;
dropDown.Id= (fieldBase as DocumentFieldSelectOne).GetValue().Id;
}
//more if statements left out for brevity
}
}
Chcę porzucić tych bezbożnych if które wykonują typ kontroli. Podejście, do którego dążyłem, polegało na stworzeniu przeciążenia metody dla każdej kombinacji pola/kontroli za pomocą typowania podklas. Na przykład:
public static void Bind(TextBox control, DocumentFieldText fieldText){
//some implementation code
}
public static void Bind(DropDown control, DocumentFieldDropDown fieldDropDown){
//some implementation code
}
Miałem nadzieję, że mogę liczyć na .NET następnie wywołać odpowiednią przeciążenie w wykonawczego pomocą określonej podklasy używany: Na przykład:
foreach (DocumentFieldBase field in fields){
Control control = FindControl(field.Identifier);
Bind(control, field)
}
Niestety, dławiki kompilatora, gdy próbuję tego: Argument "1": nie można przekonwertować z "System.Web.UI.Control" na "TextBox".
Jeśli muszę rzucić pierwszy argument do TextBox, wracam do wykonywania sprawdzania typu siebie i pokonuję cały cel tego ćwiczenia.
Czy staram się osiągnąć a) możliwe i b) dobry pomysł?
Odpowiedź przyznana, ponieważ nadałeś mojemu bólowi nazwę :) Często czytałem o podwójnej wysyłce i wzorze Odwiedzającego i miałem przeczucie, z którym miałem do czynienia (stąd wymieniany tag "wysyłkowy"). Udało Ci się również wyodrębnić istotne różnice między przesyłką pojedynczą a wysyłką wielokrotną, czego wiele artykułów na ten temat nie mogłem zrobić. –