2014-09-15 5 views
5

nehme ich eine Erweiterungsmethode schreiben möchten einige Daten aus einem T[,] in eine CSV-Dump:Lambda in C# Erweiterungsmethode

public static void WriteCSVData<T>(this T[,] data, StreamWriter sw) 
{ 
    for (int row = 0; row < data.GetLength(0); row++) 
     for (int col = 0; col < data.GetLength(1); col++) 
     { 
      string s = data[row, col].ToString(); 

      if (s.Contains(",")) 
       sw.Write("\"" + s + "\""); 
      else 
       sw.Write(s); 

      if (col < data.GetLength(1) - 1) 
       sw.Write(","); 
      else 
       sw.WriteLine(); 
     } 
} 

die ich mit

using (StreamWriter sw = new StreamWriter("data.csv")) 
    myData.WriteCSVData(sw); 

annehmen nennen könnte, aber myData ist a Complex[,] und ich möchte die Größe der komplexen Zahl, nicht den vollen Wert schreiben. Es wäre praktisch, wenn ich schreiben könnte:

using (StreamWriter sw = new StreamWriter("data.csv")) 
    myData.WriteCSVData(sw, d => d.Magnitude); 

aber ich bin nicht sicher, wie das in der Verlängerung Methode zu implementieren oder ob es überhaupt möglich.

+0

Vergessen Sie nicht, in Ihren Ausgabefeldern irgendwelche Anführungszeichen oder Zeilenumbrüche anzugeben! – Gabe

Antwort

8

Sie können eine Überlastung der vorhandenen Methode wie folgt schreiben:

public static void WriteCSVData<T, TValue>(this T[,] data, StreamWriter sw, 
    Func<T,TValue> func) 
{ 
    for (int row = 0; row < data.GetLength(0); row++) 
     for (int col = 0; col < data.GetLength(1); col++) 
     { 
      string s = func(data[row, col]).ToString(); 

      if (s.Contains(",")) 
       sw.Write("\"" + s + "\""); 
      else 
       sw.Write(s); 

      if (col < data.GetLength(1) - 1) 
       sw.Write(","); 
      else 
       sw.WriteLine(); 
     } 
} 

und verwenden Sie es so, wie Sie wollten:

using (StreamWriter sw = new StreamWriter("data.csv")) 
    myData.WriteCSVData(sw, d => d.Magnitude); 
+2

Danke, genau das habe ich gebraucht! – Ozzah

+0

-1, Ihre 'for'-loop-Version generiert eine neue Zeile für jede Zeile, während Ihre LINQ-Version eine neue Zeile für jedes Element generiert. – Gabe

+0

@Gabe du hast Recht. Ich muss übersehen haben, dass es nur eine neue Zeile für das letzte Element einer Zeile schreibt. entfernt. –

1

definieren einen Delegaten mit Parametertyp T und Typ zurückgeben Zeichenfolge. Fügen Sie der Methode WriteCSVData einen Parameter hinzu, und geben Sie den Delegaten ein.

delegate string ExtractValueDelegate<T>(T obj); 

public static void WriteCSVData<T>(this T[,] data,ExtractValueDelegte<T> extractor , StreamWriter sw) { ... } 

// calling the method 
myData.WriteCSVData(sw, d => d.Magnitude.ToString()); 
+5

Es sind keine "manuellen Delegierten" mehr nötig. .NET hat sie jetzt eingebaut - 'Func ' in diesem Fall ... – ChrFin