2012-01-30 5 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

관련 문제