2015-08-13 10 views
6

Ich habe begonnen, Interpolated Strings (neues Feature von C# 6) zu verwenden, und es ist wirklich nützlich und anmutig. Aber nach meinen Bedürfnissen muss ich das Format der Zeichenfolge an eine Methode als Parameter übergeben. So etwas weiter:Ist es möglich, interpolierte Strings als Parameter an eine Methode zu übergeben?

MyMethod(string format) 

In der Vergangenheit habe ich es in den nächsten Weg:

MyMethod("AAA{0:00}") 

Jetzt habe ich versucht, diesen Code:

MyMethod($"AAA{i:00}") 

Aber dies nicht funktioniert, weil i innerhalb der Methode erstellt wird und in diesem Kontext nicht verfügbar ist.

Ist es möglich, einen Trick zu verwenden, um interpolierte Strings als Parameter für eine Methode zu übergeben?

Antwort

7

Sie können das nicht tun, und das wäre nicht eine sehr gute Idee, entweder - es bedeutet, dass Sie lokale Variablen von einer anderen Methode verwenden.
Dies würde den Zweck dieser Funktion zu besiegen - Compiler überprüfbar String-Interpolation und Bindung an lokale Variablen haben.

C# hat mehrere gute Alternativen. Zum Beispiel mit einer Func:

public void MyMethod(Func<int,string> formatNumber) 
{ 
    int i = 3; 
    var formatted = formatNumber(i); 
} 

Verwendung als:

MyMethod(number => $"AAA{number:00}"); 

Das ist besser als das, was Sie heute haben - wo Sie den Format-String (s?) Haben und seine Verwendung in verschiedenen Orten.

Wenn Sie mehr als eine einzelne Variable haben, kann dieser Ansatz skalieren, aber Sie sollten sie in eine Klasse (oder eine Struktur) gruppieren - die func wird viel besser aussehen, und Ihr Code wird besser lesbar sein. Diese Klasse kann auch .ToString() überschreiben, was für Sie nützlich sein könnte.

Eine andere einfache Option ist, nur das Format zu übergeben: MyMethod("00") und i.ToString(format), aber das funktioniert nur in Ihrem vermutlich vereinfachten Beispiel.

+0

Ich markiere diese Antwort als am vernünftigsten. Aber ich werde diese Lösung nicht verwenden. Ich versuche, meinen Code einfach und verständlich zu halten, aber diese Lösung ist zu anspruchsvoll. Die beste Antwort ist im ersten Teil - ich kann es nicht tun. – RredCat

+1

@RredCat Ich finde diese Lösung einfach und einfach zu bedienen. Warum sagst du, es ist zu kompliziert? Weil es ein Lambda verwendet? – svick

+0

@svick Ja. Persönlich liebe ich Lambda, aber meine wahre Methode hat mehr als drei Parameter. In diesem Fall sieht der Aufruf der Methode seltsam aus, nicht klar und zu lang. (etwas wie MyMethod (param0, param1, param2, lambda)). – RredCat

0

Es ist nicht möglich. Aber die alternative Möglichkeit ist

public static string MyMethod(string format, params object[] args) 
{ 
    if (format == null || args == null) 
    throw new ArgumentNullException(format == null ? "format" : "args"); 
    return string.Format((IFormatProvider) null, format, args); 
} 

EDIT:

MyMethod("The number is {0}", 12); 

EDIT2:

public static string MyMethod(string format) 
{ 
    var i = 12; 
    var result = string.Format(null, format, i); 
    return result; 
} 
MyMethod("{0:000}"); 
+1

Dies funktioniert, aber wenn ich die Frage richtig verstanden habe, '12' aus' MyMethod' kommt, nicht von der rufenden Funktion. Was sind die Vorteile gegenüber der direkten Verwendung von 'String.Format'? – Kobi

+0

Sie können 'args' als' i' in dieser Methode anstelle von 'i' vom Aufruf der Seite verwenden, müssen aber den Parameter' args' entfernen. –

3

Es gibt mehrere Möglichkeiten, dies zu tun.

Die erste ist eine andere Methode Überlastung hinzufügen, die eine FormattableString (neues getippt durch eine der Varianten der String interpollation verwendet) nimmt und ruft das Original:

public void MyMethod(FormattableString fs) 
{ 
    MyMethod(fs.Format); 
} 

Und Sie haben auch Zugang zu die Argumente, wenn Sie müssen.

Wenn Sie das Format nur benötigen, erstellen Sie einfach eine Erweiterungsmethode zu extrahieren:

public static string AsFormat(FormattableString fs) 
{ 
    return fs.Format; 
} 
+2

Ich glaube nicht, dass dies funktioniert, da "i' innerhalb der Methode erstellt wird". – svick

+0

Ich fand die ganze Frage ein bisschen seltsam. Ich habe gerade eine Möglichkeit gezeigt, die Formatzeichenfolge aus einer interpolierten Zeichenfolge zu entfernen. –

+0

@svick Beachten Sie, dass dies die Lösung ist, aber Sie müssen "FormattableString" ganz unten verwenden (es erfasst die Parameter, die für die Formatierung erforderlich sind). – Richard

0

einige Jahre dies jedoch gefragt wurde, da ich auf diese über Google kam, während Suche nach einer Antwort, die ich hatte schon in mein Kopf, aber ich konnte mich nicht um die Implementierung/Syntax kümmern.

Meine Lösung ist weiter zu dem, was @Kobi geliefert ...

public class Person 
    { 
     public int Id {get; set;} 
     public DateTime DoB {get;set;} 
     public String Name {get;set;} 
    } 

public class MyResolver 
{ 
    public Func<Person, string> Resolve {get;set;} 
    public string ResolveToString<T>(T r) where T : Person 
    { 
     return this.Resolve(r); 
    } 
} 

// code to use here... 
var employee = new Person(); 
employee.Id = 1234; 
employee.Name = "John"; 
employee.DoB = new DateTime(1977,1,1); 

var resolver = new MyResolver(); 
resolver.Resolve = x => $"This person is called {x.Name}, DoB is {x.DoB.ToString()} and their Id is {x.Id}"; 

Console.WriteLine(resolver.ResolveToString(employee)); 

Ich habe nicht die oben auf Syntaxfehler geprüft, aber hoffentlich bekommen Sie die Idee, und Sie können jetzt einfach definieren „wie“ Sie wollen die zu suchende Zeichenfolge, aber lassen Sie die Leerzeichen zur Laufzeit abhängig von den Werten in Ihrem Person-Objekt.

Cheers,

Wayne

Verwandte Themen