2016-08-03 10 views
-1

Ich möchte jeden möglichen Typ als Funktionsparameter übergeben können.Übergeben Sie die Eigenschaft als Funktionsargument und konvertieren Sie sie in einen String innerhalb

Jetzt gibt es ein Problem mit der Weitergabe von Eigenschaften z.

class Foo 
{ 
    public int Bar { get; set; } 
} 

Ich bin in der Lage zu nutzen: nameof (Foo.Bar) aber ich bin nicht in der Lage A (Foo.Bar), wo in A zu tun nameof verwendet werden.

Ich möchte sicher haben, dass String aus Eigenschaft erstellt wird und ich möchte, dass die Eigenschaft an die API übergeben wird und nameof innerhalb der API ausgeführt wird.

Gibt es eine Möglichkeit, Eigenschaft über Funktion an nameof zu übergeben? Ich möchte die Konvertierung der Eigenschaft in eine Zeichenfolge innerhalb meiner Klasse ausblenden, anstatt die Zeichenfolge fertig zu machen. Wie erreichen Sie das?

edit: Der Schlüssel ist ungefähr: [?]

class B 
{ 
    public Prop {get; set;} 
} 

void foo([?]) 
{ 
    Console.WriteLine(nameof([?])); 
} 

Was stattdessen setzen wie Konsolenausgabe zu haben. Prop

+1

Warum nicht eine 'string' passieren und' nameof' auf der rufenden Seite nutzen? Du erkennst auch, dass 'nameof (T)' dir nur die wörtliche Zeichenkette "T" geben wird, egal welchen Typ du passierst? – juharr

+0

Sorry, falsches Beispiel, das ist sowas wie es mir gefällt zu arbeiten. Ich brauche viele Anwendungen der Schnur, so dass der Anruf durch hässlich wird. Ich möchte nameof innerhalb meiner API verstecken, um sicher zu sein, dass String von Immobilien erstellt wird, keine Dummy-Daten – senfen

+0

Vielleicht aktualisieren Sie Ihre Frage entsprechend und erklären Sie ein bisschen mehr über das, was Sie erreichen möchten? –

Antwort

1

Ich glaube, Sie nameof ein wenig hier falsch interpretieren.

In Ihrem ersten Beispiel wird die Methode immer T drucken und hängt nicht vom Typ T ab. Das Schlüsselwort nameof bewirkt nichts anderes, als den angegebenen Ausdruck durch eine Zeichenfolgendarstellung des Ausdrucks zu ersetzen. z.B. Wir geben nameof den Parameter T und er wird die Zeichenfolgendarstellung dieses Ausdrucks zurückgeben: T.

void A<T>(T smth) 
{ 
    Console.Writeline(nameof(T)); // example usage 
} 

Im Allgemeinen ist die Verwendung von nameof ist Refactoring-able Methode/Eigenschaft/... Namen Methoden zur Verfügung zu stellen.

Zum Beispiel die ArgumentOutOfRangeException hat als Parameter den Namen des Arguments, die außerhalb des zulässigen Bereichs ist.

void Test(int value) 
{ 
    if (value < 0) throw new ArgumentOutOfRangeException("value"); 
    // yada yada 
} 

Wenn wir den Namen als fest einprogrammierte Zeichenfolge wie im Beispiel bieten wir über eine Inkonsistenz erhalten würden, wenn die Parameter umbenennen.

Um dies zu lösen, verwenden wir nameof und weil wir den Parameter selbst anstelle einer fest codierten Zeichenfolge zur Verfügung stellen, ist es refaktorsicher.

void Test(int value) 
{ 
    if (value < 0) throw new ArgumentOutOfRangeException(nameof(value)); 
    // yada yada 
} 
+0

Ich weiß, wo kann ich nameof verwenden, ich frage mich, wie man es innerhalb der Funktion für übergebene Argument verwenden. Ich mache ein paar Reflektionen und ich muss die Namen der Häuser vergleichen. Ich kann machen, dass der Benutzer der API überall nameof (prop) verwendet, aber ich möchte diese innerhalb der API haben, um sicherzustellen, dass die Zeichenkette von der realen Eigenschaft erstellt wird. – senfen

+0

@senfen Es gibt keine Möglichkeit sicherzustellen, dass der Benutzer Ihnen korrekte Eingaben gibt und Sie sollten erwarten, dass er Ihnen * falsche * Eingaben gibt. Überprüfen Sie einfach, ob die angegebene Eigenschaft vorhanden ist, anstatt zu versuchen, einen 'richtigen' Eigenschaftsnamen anzugeben. –

+0

Ok, aber es sieht auch schlecht aus, wenn der Funktionsaufruf einen Namen hat, dessen Name nicht lesbar ist. Also, gibt es keine Möglichkeit, das zu erreichen? – senfen

1

der C# -Compiler Verwendungen ‚nameof‘ zu Art finden und Dinge zum Zeitpunkt der Kompilierung ersetzen, so wird es nicht funktionieren, wie Sie es erwarten. Stattdessen müssen Sie die Namen der Eigenschaften zur Laufzeit mithilfe von Expressions oder Reflection abrufen. Hier ist ein Beispiel dafür, wie es zu tun Ausdrücke verwenden:

public static string GetName<T>(Expression<Func<T>> expression) 
    { 
     var member = (MemberExpression)expression.Body; 
     return member.Member.Name; 
    } 
    public static string GetName<T>(Expression<Func<T, object>> expression) 
    { 
     var body = expression.Body as MemberExpression; 

     if (body == null) 
     { 
      body = ((UnaryExpression)expression.Body).Operand as MemberExpression; 
     } 

     return body.Member.Name; 
    } 

    public static void PrintName<T>(Expression<Func<T>> expression) 
    { 
     Console.WriteLine(GetName(expression)); 
    } 

    public static void PrintName<T>(Expression<Func<T, object>> expression) 
    { 
     Console.WriteLine(GetName(expression)); 
    } 

wie folgt verwendet:

class B 
{ 
    public Prop {get; set;} 
} 

static void Main(string[] args) 
    { 
     PrintName<B>((b) => b.Prop); 

     //Or 
     var someObject = new B(); 
     PrintName(() => someObject.Prop); 

     Console.ReadLine(); 
    } 
Verwandte Themen