2012-01-30 12 views
4

私は列挙可能なリストのCSV拡張メソッドを作成しようとしています。匿名型の拡張メソッドを書き込む方法は?

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

あなたは、私が」何を参照しています:

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

これは私が(私が間違っていると思う)拡張メソッドを作成する際に、これまで行われてきたものである:ここで私は私の単純な列挙リストを作成した方法です間違ってる?

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

あなたが本当にどのIEnumerable<T>に手を加えたり、あなたのタイプは、より具体的であるべきで拡張メソッドを記述しようとしています:

答えて

10

あなたは、メソッドのシグネチャでのジェネリック型パラメータを指定する必要がありますか?後で該当する場合は、Tをサポートするタイプに置き換えるか、十分な制約を追加する必要があります。

編集:

コメントを踏まえて - あなたの代わりにあなたのクエリ内の匿名型のクラスに投影しなければならない - あなたは、この特定のタイプの拡張方法、すなわち使用することができます。

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

今、あなたのクエリが使用できます

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

そして(今、ジェネリックである必要はありません)あなたの拡張メソッド

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

:ここ

は、完全なサンプルコードです。私のタイプはより具体的です。私の問題は、タイプが正確に使用されることがわからないということです。型を表示すると、 'System.Linq.Enumerable + d__81'と表示されます。私にはっきりとした考えを与えない。 –

+0

匿名型を使用しているため、必要な特定の汎用実装を作成することはできません。あなたがよく知られているクラスに値を入れたら、BrokenGlassの正しい解決法を使うことができます。 –

+0

@inquisitive_one:それに応じて更新された – BrokenGlass

1

あなたは反射を使用して何をしようとすることができます。しかし、非一般的なコードを書いた場合よりもパフォーマンスはやや悪くなります。それは後者である

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

さらに、パフォーマンスが問題になる場合は、Reflection.EmitまたはSystem.Linq.Expressionsのクラスを使用して、メソッドを実行時コンパイルすることができます。実行時にコードをコンパイルするコストは一度支払われますが、コードを手書きしたのと同じくらい速くメソッドを呼び出すことができます。しかし、このメソッドを生成するコードはやや複雑になります。 – MarkPflug

関連する問題