2013-07-24 3 views
6

den folgenden Code vor:dynamischen Typ anstelle von keiner möglichst generischen Eigenschaften

public dynamic DataGrid { get; private set; } 
    public DataGridForm<TData, TGrid> GridConfig<TData, TGrid>() where TData : class 
    { 
     return DataGrid = new DataGridForm<TData, TGrid>(); 
    } 

Ich versuche, in einem property zur späteren Verwendung eine Instanz einer generischen Klasse zu halten, aber wie Sie wissen:

Eigenschaften, Ereignisse, Konstruktoren usw. können nicht generisch sein - nur Methoden und Typen können generisch sein. Die meiste Zeit ist das kein Problem, aber ich zustimmen, dass es manchmal ein Schmerz (Jon Skeet)

ich wissen will, ist dies ein guter Weg, um diese Situation zu runden?

+0

Können Sie nicht die allgemeine Funktionalität in eine Schnittstelle 'IDataGridForm' setzen und dann die Eigenschaft dieses Typs haben? – Corak

+0

Ich kann dich nicht bekommen, kannst du das genauer erklären? – saber

+2

Nun, wie willst du das 'DataGridForm' benutzen? Zum Beispiel stelle ich mir vor, dass Sie ein Formular anzeigen möchten. Machen Sie eine Schnittstelle 'IDataGridForm' mit einer Methode' Display() '. Lassen Sie nun Ihre Klasse 'DataGridForm diese Schnittstelle implementieren. Es muss diese 'Display()' Methode haben, um das zu tun. Habe jetzt eine Eigenschaft 'public IDataGridForm DataGrid {get; privates Set; } '. Diese Eigenschaft kann jetzt ein 'DataGridForm ' enthalten und Sie können 'Display()' dort anzeigen, wo Sie möchten. – Corak

Antwort

1

Wie die Antwort im Kommentar angegeben ist, können Sie dies mit einer Basisklasse oder einer Schnittstelle:

class DataGridForm {} 
class DataGridForm<TData, TGrid> : DataGridForm {} 

class GridConfigurator 
{ 
    public DataGridForm DataGrid { get; private set; } 
    public DataGridForm<TData, TGrid> GridConfig<TData, TGrid>() where TData : class 
    { 
     return DataGrid = new DataGridForm<TData, TGrid>(); 
    } 
} 

Eine Tonne Typen und Schnittstellen in C# auf diese Weise erweitert wurde, als Generika wurde hinzugefügt. Allerdings würde ich wahrscheinlich Ihr Design neu bewerten, so dass vielleicht alles, was GridConfig() genannt wurde, das DataGridForm zwischenspeichert, da es die Typen kennt. Als ein Beispiel, ich mache eine sehr ähnliche Sache in meinem Code:

Ihr spezifischer Anwendungsfall unterstützt möglicherweise diesen Stil nicht.

+0

Ich erkannte, was Sie erklärte, ist nicht meine Anforderungen, was, wenn ich habe eine Methode in 'DataGridForm' haben, die' DataGridForm 'zurückgibt. In dieser Situation muss ich den Basistyp auch zu einem generischen Typ machen. Habe ich recht? – saber

+0

Nicht, wenn es eine Methode ist, aber ja, wenn es eine Eigenschaft ist. In meinem zweiten Beispiel konnte Vector von Vector ohne Problem erben. – lukegravitt

+0

Sollte der Rückgabetyp von Vector.Create nicht Vector sein? – marcob

0

In diesem Fall muss Ihr Typ selbst generisch sein.

class GridConfigurator<TData, TGrid> 
     where TData : class 
    { 
     public DataGridForm<TData, TGrid> DataGrid { get; private set; } 
     public DataGridForm<TData, TGrid> GridConfig<TData, TGrid>() 
     { 
      return DataGrid = new DataGridForm<TData, TGrid>(); 
     } 
    } 

Aber ich verstehe nicht den Zweck dieser Klasse. Die GridConfig-Methode hat einen nicht offensichtlichen Nebeneffekt beim Festlegen der DataGrid-Eigenschaft (die über einen privaten Setter verfügt). Wenn ich diese Klasse verwenden würde, würde ich niemals vermuten, dass der Wert, den GridConfig() mir zurückgibt, auch als DataGrid-Eigenschaft festgelegt ist. Mit anderen Worten:

var configurator = new GridConfigurator(); 
var firstGrid = configurator.GridConfig(); 
var firstReference = configurator.DataGrid; 
var secondGrid = configurator.GridConfig(); 
var secondReference = configurator.DataGrid; 

würde ich folgendes würde return false annehmen:

object.ReferenceEquals(firstGrid, secondGrid); 

Aber ich würde davon ausgehen, das wahr zurückkehren würde:

object.ReferenceEquals(firstReference, secondReference); 

Da zu keinem Zeitpunkt in den obigen Code zuweisen ich jemals die DataGrid-Eigenschaft. Es ist nicht klar, dass eine Methode namens GridConfig() diesen Effekt haben würde.

Den einschließenden Typ (GridConfigurator) auch generisch zu machen scheint den Zweck dessen, was Sie versuchen, zu besiegen. Warum sollte jemand diesen Typ verwenden, wenn er stattdessen nur einen direkten Verweis auf DataGridForm verwenden könnte?

Wenn die GridConfig Methode soll etwas mehr tun, als nur eine neue Standardinstanz von DataGridForm zuweisen, dann machen es eine statische Factory-Klasse wie folgt aus:

static class GridConfigurator 
{ 
    public static DataGridForm<TData,TGrid> GridConfig<TData, TGrid>(...) where TData: class 
    { 
    var grid = new DataGridForm<TData,TGrid>(); 
    // do something with the parameters to this method to initialize the instance. 
    return grid; 
    } 
} 

ich auch das Verfahren etwas anderes nennen würde als GridConfig. Wie Configure() oder Create().

Verwandte Themen