2010-11-24 19 views
2
public class TimeZone 
{ 
    public int Id { get; set; } 
    public string DisplayName{ get; set; } 
} 

In einer anderen Klasse ich habe:C# Wie erhält man den Namen einer Klasseneigenschaft?

var gmtList = new SelectList(
     repository.GetSystemTimeZones(), 
     "Id", 
     "DisplayName"); 

Hinweis: System.Web.Mvc.SelectList

Ich mag auf den Eigenschaftsnamen mit "Id" nicht haben, schreiben und "DisplayName". Später wird sich der Eigenschaftsname möglicherweise ändern und der Compiler wird diesen Fehler nicht erkennen. C# Wie bekomme ich den Namen einer Eigenschaft in eine Zeichenfolge?

UPDATE 1

Mit Hilfe von Christian Hayter, kann ich verwenden:

var tz = new TimeZone(); 
var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    NameOf(() => tz.Id), 
    NameOf(() => tz.TranslatedName)); 

ODER

var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    NameOf(() => new TimeZone().Id), 
    NameOf(() => new TimeZone().TranslatedName)); 

Wenn jemand andere Idee hat, ohne die Notwendigkeit einer Schaffung neues Objekt Fühlen Sie sich frei, es zu teilen :) danke.

Antwort

13

Sie könnten eine Hilfsmethode erstellen den Namen der Eigenschaft von einem Ausdrucksbaum zu extrahieren, wie folgt aus:

string NameOf<T>(Expression<Func<T>> expr) { 
    return ((MemberExpression) expr.Body).Member.Name; 
} 

Dann können Sie es nennen wie folgt:

var gmtList = new SelectList(repository.GetSystemTimeZones(), 
    NameOf(() => tz.Id), 
    NameOf(() => tz.DisplayName)); 

Beachten Sie, dass jede Instanz der Klasse nur den Namen ausführt, da Sie den Eigenschaftswert nicht lesen.

+0

Dies ist eine großartige Lösung, aber bedenken Sie jeglichen Leistungsaufwand durch die Verwendung von Ausdrucksbäumen sowie das Ausmaß an Refactoring, das erforderlich ist, wenn alle Verweise geändert werden müssen. Es kann sogar vernachlässigbar sein, aber es gibt nur einen Weg, das herauszufinden! –

+1

Ich habe dies nicht profiliert, aber theoretisch arbeitet der Code von einem Ausdruck-Baum-Objekt-Graphen, der bereits vom Compiler erstellt wurde, daher sollte es ziemlich schnell sein, den Namen zu lesen. Wenn Sie den * Wert * des Ausdrucks lesen möchten, ist das eine ganz andere Sache! –

+0

Irgendwelche Leistungsprüfungen dabei? Wäre es ratsam, es mit MVVM INotifyPropertyChanged zu verwenden? –

0

(Das sind keine Parameter btw, sie sind Eigenschaften.)

Nun, eine Möglichkeit ist, die Delegierten zu verwenden. Zum Beispiel:

public class SelectList<T> 
{ 
    public SelectList(IEnumerable<T> source, 
         Func<T, string> idProjection, 
         Func<T, string> displayProjection) 
    { 
     ... 
    } 
} 

Dann:

var gmtList = new SelectList<TimeZone>(repository.GetSystemTimeZones(), 
             tz => tz.Id, tz => tz.DisplayName); 
+0

Nizza Option verwenden, aber die 'System.Web.Mvc.SelectList' kann nicht mit Typ-Argumente verwendet werden. Also kann ich diese Lösung nicht verwenden. Danke trotzdem :) – asdas

+1

@asdas: Wenn du gesagt hättest, mit welchem ​​Typ es anfangen soll, hätte das sehr geholfen. Du hast uns keinen Kontext gegeben. –

0

var name = (string) typeof(TimeZone).GetProperty("DisplayName").GetValue(0);

+0

Noch einmal schreiben Sie den DisplayName mit Anführungszeichen. Nicht was ich suche :) Danke trotzdem. – asdas

+0

Sie können es durch eine Variable ersetzen, die ihren Wert von einer externen Datenquelle bekommt, alberne:) –

0
string id=typeof(TimeZone).GetProperties()[0].Name; 
string displayName=typeof(TimeZone).GetProperties()[1].Name; 


var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    id, 
    displayName); 

dies funktionieren wird, es sei denn, die Reihenfolge, in der ID und Display erklärt sich nicht verändert. oder Sie können ein Attribut für die Eigenschaft definieren, um zwischen ID und Anzeigename zu unterscheiden.

+0

Ist eine funktionierende Lösung :) aber nicht sehr praktisch und kugelsicher. Vielen Dank. – asdas

0

Da C# 6.0 können Sie jetzt

var gmtList = new SelectList(
    repository.GetSystemTimeZones(), 
    nameof(TimeZone.Id), 
    nameof(TimeZone.DisplayName)); 
Verwandte Themen