Benutzer mit den meisten Antworten
Probleme bei der Deklaration einer Schnittstelle mit Generics

Frage
-
Hallo
Ich habe ein Problem bei der Deklaration einer Schnittstelle – in Verbindung mit Generics. Folgendes Szenario möchte ich abdecken –
Es gibt verschiedene Daten-SuchMasken – die alle von einer BaseSuchMasken-Klasse ableiten; von jeder SuchMaske kann immer der ausgewählte PrimaryKey des Datensatzes zurückgegeben werden an den Aufrufer; jetzt habe ich das Problem, dass ich einmal <GUID> als Prim.Key haben, und dann wieder <int>.
Ich wollte das sauber lösen, indem ich eine Schnittstelle deklariere mit einer Methode wo der Rückgabe-Parameter als Generic deklariert wird – diese Schnittstelle sollte in die BaseSuchMasken-Klasse.
Ich schaffe es aber leider nicht, die Schnittstelle bei der Base-Klasse richtig einzufügen. Ich kann es derzeit in den einzelnen abgeleiteten Klassen………aber dann muss ich erst recht wieder die Methode jedes mal implementieren
public partial class FormSearchLeistungen : PhysioApplication.FormSearchBase, ISearchSelectedPrimaryKey<int> { … … #region ISearchSelectedPrimaryKey<int> Members public int GetSelectedPrimaryKey() { int foundPrimKey = Convert.ToInt32(gridView.GetRowCellValue(gridView.FocusedRowHandle, gridView.Columns["PrimaryKey"])); return foundPrimKey; } #endregion }
Wie kann ich das Ganze in die Base-Klasse geben, so dass ISearchSelectedPrimaryKey als Generic fungiert, und die GetSelectedPrimKey()-Methode einen Generic zurückgibt ???
Kann mir dazu bitte jemand weiterhelfen ?
Vielen Dank & schönen Gruß
Michael
Antworten
-
Hallo Michael,
Wäre die Idee von mir nicht die leichtere Lösung - wenn das mit dem null-Problem gelöst wäre ?? Hast Du vielleicht auch einen Rat bez. der null-Problematik?
Es macht natürlich keinen Sinn, eine Schnittstelle zu implementieren, die nicht gebraucht wird.
Die Idee mit der generischen Methode vereinfacht natürlich das Ganze etwas (aber Null zurückzugeben scheint mir keine gute Idee zu sein, dann schon eher default(T) da man nicht wissen kann, ob T ein Referenztyp oder ein Werttyp ist). Genaugenommen, würde ich diese ganze Funktionalität aus dem Form-Objekt herausnehmen und in eine separate Klasse kapseln, die ich dann mit der Form- oder DataGridView- oder BindingSource-Instanz konfigurieren kann.Gruß
Marcel- Als Antwort markiert M.Erlinger Mittwoch, 11. August 2010 15:08
Alle Antworten
-
Hallo Michael,
Falls ich Dich richtig verstehe, könntest Du in etwa so vorgehen:
public interface ISearchSelectedPrimaryKey<T> { T GetSelectedPrimaryKey(); } public class FormSearchBase<T> : ISearchSelectedPrimaryKey<T> { #region ISearchSelectedPrimaryKey<T> Member public T GetSelectedPrimaryKey() { T foundPrimKey = (T) GetPrimaryKeyValue(); return foundPrimKey; } #endregion }
Um mehr zu sagen, fehlt mir das größere Bild.
Gruß
Marcel -
Hallo
Danke für Deine Rückmeldung. Ich habe Deinen Code natürlich gleich probiert - und ich war auch schon soweit einmal.
Das Problem liegt daran, sobald ich den Code anpasse - auch so wie Dein Vorschlag aussieht - funktioniert die WinFormKlasse nicht mehr. Er kennt dann zum Beispiel "InitializeComponent()" nicht mehr - und bei allen Controls die im Source angesprochen werden gibt es einen CompilerFehler.
Liegt das vielleicht an der WinForm-Klasse in Verbindung mit Generics ?
Danke & schönen Gruß
Michael
-
Hallo Michael,
> Liegt das vielleicht an der WinForm-Klasse in Verbindung mit Generics ?
Ja. Es hat aber nicht direkt mit Windows Forms zu tun, sondern mit den Limitierungen des Windows Forms Designers in Bezug auf Generics. Du kannst Dir dennoch behelfen, indem Du eine Klasse von FormSearchBase<T> ableitest, z.B. FormSearchIntBase : FormSearchBase<int>, und die vom Designer zu bearbeitende Form dann von MyFormSearchIntBase ableitest, z.B. Form1 : FormSearchIntBase. Natürlich muss dabei die Basisklasse FormSearchBase<T> von System.Windows.Forms.Form abgeleitet sein, also: public class FormSearchBase<T> : Form, ISearchSelectedPrimaryKey<T>.Gruß
Marcel -
Hallo Marcel
eigentlich bin ich gerade d'rauf gekommen, dass ich es viel einfacher lösen könnte - ohne Interface, nur die Methode in der BasisKlasse "FormSearchBase" als generische Methode implementieren......
public T getSelectedPrimKey<T>() { if (gridView.RowCount > 0) { T primaryKey = (T)gridView.GetRowCellValue(gridView.FocusedRowHandle, gridView.Columns["PrimaryKey"]); return primaryKey; } else { // do something....... return null; } }
Nur gibt es da Probleme mit dem "null"-Return. Wenn ich die Methoden-Deklaration auf
public Nullable<T> getSelectedPrimKey<T>() { }
ändere, dann kommt auch eine Compiler-Fehlermeldung "The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method "
Wäre die Idee von mir nicht die leichtere Lösung - wenn das mit dem null-Problem gelöst wäre ?? Hast Du vielleicht auch einen Rat bez. der null-Problematik?
Danke schon mal und schönen Gruß
Michael
-
Hallo Michael,
Wäre die Idee von mir nicht die leichtere Lösung - wenn das mit dem null-Problem gelöst wäre ?? Hast Du vielleicht auch einen Rat bez. der null-Problematik?
Es macht natürlich keinen Sinn, eine Schnittstelle zu implementieren, die nicht gebraucht wird.
Die Idee mit der generischen Methode vereinfacht natürlich das Ganze etwas (aber Null zurückzugeben scheint mir keine gute Idee zu sein, dann schon eher default(T) da man nicht wissen kann, ob T ein Referenztyp oder ein Werttyp ist). Genaugenommen, würde ich diese ganze Funktionalität aus dem Form-Objekt herausnehmen und in eine separate Klasse kapseln, die ich dann mit der Form- oder DataGridView- oder BindingSource-Instanz konfigurieren kann.Gruß
Marcel- Als Antwort markiert M.Erlinger Mittwoch, 11. August 2010 15:08