How to write extension methods for anonymous types?

I am trying to create a CSV extension method for my enumerated list, and I'm at a dead end. This is how I created my simple enumerated list:

var CAquery = from temp in CAtemp join casect in CAdb.sectors on temp.sector_code equals casect.sector_code select new { CUSIP = temp.equity_cusip, CompName = temp.company_name, Exchange = temp.primary_exchange }; CAquery.WriteToCSVFile(); 

This is what I have done so far in creating the extension method (which I think is wrong):

 public static class CSVExtensions { public static void WriteToCSVFile(this IEnumerable<T> myList) { 

Do you see what I'm doing wrong?

+4
source share
2 answers

You must specify a generic type parameter in the method signature:

 public static class CSVExtensions { public static void WriteToCSVFile<T>(this IEnumerable<T> myList) { //your code here } } 

Are you really trying to write an extension method that should work on any IEnumerable<T> or is your type more specific? If in the latter case, you must replace T with the type you want to support (or add sufficient restrictions).

Edit:

In light of the comments - you should project the class instead of the anonymous type in your query - then you can use the extension method for this particular type, that is:

 class CompanyTicker { public string CUSIP {get;set;} public string CompName {get;set;} public string Exchange {get;set;} } 

Now your request could be:

 var CAquery = from temp in CAtemp join casect in CAdb.sectors on temp.sector_code equals casect.sector_code select new CompanyTicker { CUSIP = temp.equity_cusip, CompName = temp.company_name, Exchange = temp.primary_exchange }; 

And your extension method (which now does not have to be general):

 public static class CSVExtensions { public static void WriteToCSVFile(this IEnumerable<CompanyTicker> myList) { //your code here } } 
+10
source

You can do what you are trying to do using reflection. Performance will be slightly worse than if you are not writing generic code.

Here is a complete code example:

 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; class Program { static void Main(string[] args) { var seq = Enumerable.Range(0, 100) .Select(i => new { Name = "Item" + i, Value = i }) ; seq.WriteCsv(Console.Out); Console.ReadLine(); } } public static class CsvExtension { public static void WriteCsv<T>(this IEnumerable<T> seq, TextWriter writer) { var type = typeof(T); MethodInfo[] getters = type.GetProperties().Select(pi => pi.GetGetMethod()).ToArray(); // only supporting simple properties // indexer properties will probably fail var args = new object[0]; foreach (var item in seq) { for (int i = 0; i < getters.Length; i++) { if (i != 0) writer.Write(","); Object value = getters[i].Invoke(item, args); var str = value.ToString(); if (str.Contains(",") || str.Contains("\"")) { var escaped = str.Replace("\"", "\\\""); writer.Write("\""); writer.Write(escaped); writer.Write("\""); } else { writer.Write(str); } } writer.WriteLine(); } } } 
+1
source

Source: https://habr.com/ru/post/1393813/


All Articles