2009-03-16 5 views
7

Ich spreche nicht über generische Klassen, die Eigenschaften oder Felder mit dem Typ eines generischen Parameters deklarieren. Ich spreche über generische Eigenschaften, die sowohl auf generische als auch auf nicht-generische Klassen angewendet werden können.Denken Sie, dass generische Eigenschaften in .NET nützlich wären?

Ich rede nicht darüber nach:

public class Base<T> 
{ 
    public T BaseProperty { get; set; } 
} 

Ich spreche über diese:

public class Base 
{ 
    public T BaseProperty<T> 
    { 
     get 
     { 
      // Insert magic 
     } 
     set 
     { 
      // Insert magic 
     } 
    } 
} 

Oder diese:

public class Base<U> 
{ 
    public T BaseProperty<T> 
    { 
     get 
     { 
      // Insert magic 
     } 
     set 
     { 
      // Insert magic 
     } 
    } 

    public U OtherBaseProperty { get; set; } 
} 

Die Nutzung wäre in etwa so gehen :

var b = new Base(); 
b.BaseProperty<int> = 42; 
int i = b.BaseProperty<int>; 
b.BaseProperty<string> = "Hi"; 
string s = b.BaseProperty<string>; 

Oder für das zweite Beispiel:

var b = new Base<string>(); 
b.BaseProperty<int> = 42; 
int i = b.BaseProperty<int>; 
b.OtherBaseProperty = "Hi"; 
string s = b.OtherBaseProperty; 

Der // Insert Magie bezieht sich jeden Anruf an die allgemeine Eigenschaft Getter oder Setter Handhabung, die einen anderen Typ für den Typ-Parameter hat.

Zum Beispiel diese:

b.BaseProperty<int> = 42; 

Needs anders behandelt werden:

b.BaseProperty<string> = "Hi"; 

ich, dass für jeden Typ T ins Auge fassen würde, wenn der Getter genannt wird, bevor der Setter dann standardmäßig aufgerufen wird (T) wird zurückgegeben. Wenn der Setter aufgerufen wird, wird der Wert pro Typ T gespeichert, so dass beim nachfolgenden Aufruf des Getter der vorherige Wert zurückgegeben wird, der für diesen Typ festgelegt wurde.

Beachten Sie, dass unter den Abdeckungen Eigenschaften nur Methoden sind.

Denkst du, das wäre nützlich?

+0

Nein, es scheint nicht so nützlich zu sein. Wenn ich eine Int-Eigenschaft brauche, werde ich eine machen. Wenn ich eine String-Eigenschaft brauche, mache ich eine. Ziemlich einfach. –

Antwort

10

Ich hatte ein paar Mal, wo ich gerne die Möglichkeit gehabt hätte, dies zu tun, ja.

Allerdings wäre die Syntax ziemlich hässlich, und es ist selten genug nützlich, dass ich denke, ich bevorzuge es einfach saugen und mit generischen Methoden gehen.

+0

In der Tat, es war einmal oder zweimal, wenn es praktisch gewesen wäre. Ich habe Mads Torgersen @ MS einmal darüber befragt und im Grunde gesagt: "Warum willst du das machen?" Mit anderen Worten, die Randfälle sind nicht zwingend genug. – core

+0

Diese Eigenschaften können mit Eigenschaften implementiert werden: http://scg.unibe.ch/Research/Rotor/index.html, leider für .Net haben sie es nie aus der Forschung geschafft ... –

+0

Danke Jon. Ich genieße dein Buch übrigens sehr. Ich habe letzte Nacht nur über Generika gelesen und hatte diese Idee. –

1

Ohne einen Killer-Anwendungsfall, nein. Sie können das gleiche mit ein paar generischen Methoden erreichen, wenn Sie es brauchen.

0

Wenn aus unerfindlichen Gründen Sie es wollten entschieden, Sie von gefälschten es mit Methoden sortieren könnte:

public class Thing 
{ 
    Dictionary<Type, object> xDict = new Dictionary<Type,object>(); 
    public void set_X<T>(T x) 
    { 
     xDict[typeof(T)] = x; 
    } 
    public T get_X<T>() 
    { 
     return (T)xDict[typeof(T)]; 
    } 
} 

Warum wollen Sie ist eine ganz andere Sache, though. Es ist in der Regel sinnvoller, mit etwas zu beginnen, das Sie tun möchten, als auf eine bestimmte Art und Weise.

1

Nr

Allgemeine Methoden sinnvoll, weil sie einige (generic) Betrieb verkörpern, die sinnvollerweise auf verschiedene Arten angewendet werden können.

Aber Eigenschaften sind nur als eindeutig benannte Werte mit eindeutigem Inhalt sinnvoll. 'Generische Eigenschaften', wie Sie es vorschlagen, bestehen nur aus gleichnamigen Eigenschaften mit unterschiedlicher Signatur und unterschiedlichem Inhalt.

1

Hier ist ein Beispiel, wo es für mich praktisch gewesen wäre, wenn es möglich gewesen wäre.

var settings = new Settings(); 
int timeout = settings<int>["CacheInMinutes"]; 

Hier wird eine XML-Datei mit Konfigurationsvariablen geladen.

, dass im Vergleich zu:

var settings = new Settings(); 
int timeout = int.Parse(settings["CacheInMinutes"]); 

wirklich nicht viel Unterschied, aber hey, ich würde immer noch die allgemeine Indexer bevorzugt hat.

+0

Ja, aber "int Timeout = settings.Get (" CacheInMinutes ");" ist genauso knapp und benötigt keine Sprachumschaltung/Ergänzung zu implementieren. – Chris

+0

Gute Eins. Indexer sehen wie ein guter Anwendungsfall aus: Sitzung ["CurrentUser"] = new User(); ... var user = Sitzung ["CurrentUser"]; –

1

Nun, ich habe die Situation, die generische Eigenschaft in nicht-generischen Klasse benötigen.

Beispiel Sie haben IComponent Klasse, die ihre übergeordnete IContainer mit Eigenschaft Parent bereitstellen möchten, da die Komponente zu einem beliebigen Containertyp gehören kann. so dass Sie generische Eigenschaft zur Verfügung stellen müssen, anstatt generische Methode

Component c = new Component(); 
Container p = new Container(); 
p.Add(c); 

und dann greifen Sie auf die Mutter generic Eigenschaft (nicht aplicable jetzt) ​​

c.Parent.ContainerProperty; 
c.Parent.ContainerMethod(); 

eher mit ausführlichen Verfahren wie

c.Parent().ContainerProperty; 
c.Parent().ContainerMethod(); 

Nun, in diesem Fall ist generische Eigenschaft schöner und sinnvoll, da Sie kein Argument eingeben müssen.