Ozzah
Ozzah

Reputation: 10701

Lambda in C# extension method

Suppose I want to write an extension method to dump some data from a T[,] to a CSV:

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();
        }
}

which I could call with

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

but suppose myData is a Complex[,] and I want to write the magnitude of the complex number, not the full value. It would be handy if I could write:

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

but I'm not sure how to implement that in the extension method or if it's even possible.

Upvotes: 6

Views: 284

Answers (2)

Eren Ers&#246;nmez
Eren Ers&#246;nmez

Reputation: 39085

You can write an overload of your existing method like this:

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();
        }
}

and use it the way you wanted:

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

Upvotes: 8

Sercan
Sercan

Reputation: 327

Define a delegate with parameter type T and return type string. Add a parameter to method WriteCSVData with type the delegate.

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());

Upvotes: 1

Related Questions