CSV स्ट्रिंग में एक सामान्य सूची परिवर्तित करना


139

मेरे पास पूर्णांक मानों की एक सूची है (सूची) और कॉमा सीमांकित मूल्यों की एक स्ट्रिंग उत्पन्न करना चाहेंगे। सूची आउटपुट में सभी आइटम एकल अल्पविराम सीमांकित सूची में हैं।

मेरे विचार ... 1. सूची को एक विधि में पास करें। 2. सूची को पुनरावृत्त करने के लिए स्ट्रिंगर का उपयोग करें और अल्पविराम संलग्न करें 3. अंतिम चरित्र का परीक्षण करें और यदि यह अल्पविराम है, तो इसे हटा दें।

आपके क्या विचार हैं? क्या यह सबसे अच्छा तरीका है?

यदि मैं भविष्य में न केवल पूर्णांक (मेरी वर्तमान योजना) बल्कि तार, लंबे, डबल्स, बूल इत्यादि को संभालना चाहता था तो मेरा कोड कैसे बदल जाएगा? मुझे लगता है कि यह किसी भी प्रकार की सूची को स्वीकार करता है।

जवाबों:


243

यह आश्चर्यजनक है कि फ्रेमवर्क हमारे लिए पहले से क्या करता है।

List<int> myValues;
string csv = String.Join(",", myValues.Select(x => x.ToString()).ToArray());

सामान्य मामले के लिए:

IEnumerable<T> myList;
string csv = String.Join(",", myList.Select(x => x.ToString()).ToArray());

जैसा कि आप देख सकते हैं, यह प्रभावी रूप से अलग नहीं है। इस बात से सावधान रहें कि यदि आपको कॉमा है तो वास्तव x.ToString()में उद्धरण (यानी "\"" + x.ToString() + "\"") में लपेटने की आवश्यकता हो सकती है x.ToString()

इस के एक मामूली संस्करण पर एक दिलचस्प पढ़ने के लिए: एरिक लिपर्ट के ब्लॉग पर कोमा क्विबलिंग देखें ।

नोट: आधिकारिक तौर पर .NET 4.0 जारी होने से पहले यह लिखा गया था। अब हम सिर्फ कह सकते हैं

IEnumerable<T> sequence;
string csv = String.Join(",", sequence);

अधिभार का उपयोग करना String.Join<T>(string, IEnumerable<T>)। यह विधि स्वचालित रूप से प्रत्येक तत्व xको प्रोजेक्ट करेगी x.ToString()


List<int>Selectजब तक मैं कुछ याद नहीं कर रहा हूँ, तब तक फ्रेमवर्क 3.5 में विधि नहीं है ।
अजेह

2
@ हजीह: आप शायद एक usingबयान याद कर रहे हैं ।
जेसन

कौन सा विशिष्ट आयात?
अजेह

1
प्रयास करें System.Linq.Enumerable(और निश्चित रूप से आपको System.Core.dllविधानसभा की आवश्यकता होगी , लेकिन संभवतः आपके पास पहले से ही है)। तुम देखो, एक विधि के रूप में List<int> कभी नहीं है Select। बल्कि, एक विस्तार विधि के रूप में System.Linq.Enumerableपरिभाषित करता है , जिसमें से एक उदाहरण है। इस प्रकार, आपको इस एक्सटेंशन विधि को चुनने के लिए अपने आयात की आवश्यकता है। SelectIEnumerable<T>List<int>System.Linq.Enumerable
जेसन

यदि आप संख्यात्मक मानों के साथ काम कर रहे हैं और अल्पविराम एक समस्या है (स्थान के आधार पर), तो एक विकल्प है x.ToString(CultureInfo.InvariantCulture)। यह अवधि को दशमलव विभाजक के रूप में उपयोग करेगा।
हेलटनबीकर

15

3.5 में, मैं अभी भी ऐसा करने में सक्षम था। इसकी बहुत अधिक सरल और महत्वपूर्ण लंबोदर की जरूरत है।

String.Join(",", myList.ToArray<string>());

ToArray()List<int>जब तक मैं कुछ याद नहीं कर रहा हूँ, तब तक फ्रेमवर्क 3.5 में टाइप तर्क के साथ विधि का उपयोग नहीं किया जा सकता है।
अजेह

प्रतिभाशाली। ToArray के लिए कोई आवश्यकता नहीं है <string> चाइल्ड ToString () का उपयोग किया जाता है।
क्रिश्चियन

11

आप एक विस्तार विधि बना सकते हैं जिसे आप किसी भी IEnumerable पर कॉल कर सकते हैं:

public static string JoinStrings<T>(
    this IEnumerable<T> values, string separator)
{
    var stringValues = values.Select(item =>
        (item == null ? string.Empty : item.ToString()));
    return string.Join(separator, stringValues.ToArray());
}

तब आप मूल सूची पर विधि को कॉल कर सकते हैं:

string commaSeparated = myList.JoinStrings(", ");

7

आप उपयोग कर सकते हैं String.Join

String.Join(
  ",",
  Array.ConvertAll(
     list.ToArray(),
     element => element.ToString()
  )
);

ConvertAllयहां कॉल करने के लिए सामान्य प्रकार के मापदंडों को निर्दिष्ट करने की आवश्यकता नहीं है - दोनों intऔर stringअनुमान लगाया जाएगा।
पावेल मिनाव डे

1
सूची में करने के बजाय Array.ConvertAll(...' you can just do .ConvertAll (e => e.ToString ())। ToArray) `, बस कम टाइपिंग।
डेविड

string.Join (",", सूची); ठीक ही करेंगे :)
क्रिश्चियन

6

यदि कोई भी निकाय स्ट्रिंग की सूची के बजाय कस्टम वर्ग की वस्तुओं की सूची में परिवर्तित करना चाहता है, तो अपनी कक्षा के सीएसवी पंक्ति प्रतिनिधित्व के साथ अपनी कक्षा की ToString विधि को ओवरराइड करें।

Public Class MyClass{
   public int Id{get;set;}
   public String PropertyA{get;set;}
   public override string ToString()
   {
     return this.Id+ "," + this.PropertyA;
   }
}

फिर इस वर्ग सूची को हेडर कॉलम के साथ सीएसवी में बदलने के लिए निम्न कोड का उपयोग किया जा सकता है

string csvHeaderRow = String.Join(",", typeof(MyClass).GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(x => x.Name).ToArray<string>()) + Environment.NewLine;
string csv= csvHeaderRow + String.Join(Environment.NewLine, MyClass.Select(x => x.ToString()).ToArray());

myExampleCollection.Select बजाय MyClass.Select
Piotr Ferenc

5

@Frank द्वारा दिए गए लिंक में कोड के रूप में .नेट जेनेरिक सूची से एक CSV फ़ाइल बनाएँ एक ,I के साथ हर पंक्ति को समाप्त करने का एक छोटा मुद्दा था I इससे छुटकारा पाने के लिए कोड को संशोधित किया गया था। हालांकि यह किसी की मदद करता है।

/// <summary>
/// Creates the CSV from a generic list.
/// </summary>;
/// <typeparam name="T"></typeparam>;
/// <param name="list">The list.</param>;
/// <param name="csvNameWithExt">Name of CSV (w/ path) w/ file ext.</param>;
public static void CreateCSVFromGenericList<T>(List<T> list, string csvCompletePath)
{
    if (list == null || list.Count == 0) return;

    //get type from 0th member
    Type t = list[0].GetType();
    string newLine = Environment.NewLine;

    if (!Directory.Exists(Path.GetDirectoryName(csvCompletePath))) Directory.CreateDirectory(Path.GetDirectoryName(csvCompletePath));

    if (!File.Exists(csvCompletePath)) File.Create(csvCompletePath);

    using (var sw = new StreamWriter(csvCompletePath))
    {
        //make a new instance of the class name we figured out to get its props
        object o = Activator.CreateInstance(t);
        //gets all properties
        PropertyInfo[] props = o.GetType().GetProperties();

        //foreach of the properties in class above, write out properties
        //this is the header row
        sw.Write(string.Join(",", props.Select(d => d.Name).ToArray()) + newLine);

        //this acts as datarow
        foreach (T item in list)
        {
            //this acts as datacolumn
            var row = string.Join(",", props.Select(d => item.GetType()
                                                            .GetProperty(d.Name)
                                                            .GetValue(item, null)
                                                            .ToString())
                                                    .ToArray());
            sw.Write(row + newLine);

        }
    }
}

अतिरिक्त जानकारी: प्रक्रिया 'c: \ temp \ मिलान \ _MainWav.csv' फ़ाइल तक नहीं पहुँच सकती क्योंकि इसका उपयोग किसी अन्य प्रक्रिया के लिए किया जा रहा है। फ़ोल्डर devमौजूद है, लेकिन फ़ाइल नहीं ... क्या मैं उस अधिकार का उपयोग नहीं कर रहा हूं?
टॉम स्टिकेल

File.Create विधि फ़ाइल बनाता है और फ़ाइल पर एक FileStream खोलता है। तो आपकी फाइल पहले से ही खुली हुई है। आपको वास्तव में फ़ाइल की आवश्यकता नहीं है। बिलकुल सही तरीका चुनें:
डेविड

यदि कोई गुण शून्य हैं, तो क्या उसके आसपास कोई रास्ता है?
डेनियल जैक्सन

@DanielJackson आप इस कथन में एक क्लॉज़ लिख सकते हैं जहां sw.Write(string.Join(",", props.Select(d => d.Name).ToArray()) + newLine);परीक्षण नहीं किया गया है, लेकिन पता नहीं है कि आप क्या हासिल करने की कोशिश कर रहे हैं
अली उमैर

4

मैं इसे इस पोस्ट में गहराई से समझाता हूं । मैं यहाँ संक्षिप्त विवरण के साथ कोड पेस्ट करूँगा।

यहां वह विधि है जो हेडर पंक्ति बनाता है। यह स्तंभ नामों के रूप में गुण नामों का उपयोग करता है।

private static void CreateHeader<T>(List<T> list, StreamWriter sw)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        for (int i = 0; i < properties.Length - 1; i++)
        {
            sw.Write(properties[i].Name + ",");
        }
        var lastProp = properties[properties.Length - 1].Name;
        sw.Write(lastProp + sw.NewLine);
    }

यह विधि सभी मान पंक्तियों को बनाता है

private static void CreateRows<T>(List<T> list, StreamWriter sw)
    {
        foreach (var item in list)
        {
            PropertyInfo[] properties = typeof(T).GetProperties();
            for (int i = 0; i < properties.Length - 1; i++)
            {
                var prop = properties[i];
                sw.Write(prop.GetValue(item) + ",");
            }
            var lastProp = properties[properties.Length - 1];
            sw.Write(lastProp.GetValue(item) + sw.NewLine);
        }
    }

और यहाँ विधि है जो उन्हें एक साथ लाती है और वास्तविक फ़ाइल बनाती है।

public static void CreateCSV<T>(List<T> list, string filePath)
    {
        using (StreamWriter sw = new StreamWriter(filePath))
        {
            CreateHeader(list, sw);
            CreateRows(list, sw);
        }
    }

1
यह बहुत अच्छा काम करता है। मैंने डेलिमिटर को एक पैरामीटर के रूप में पारित करने के लिए इसे बेहतर किया है, इसलिए किसी भी प्रकार की सीमांकित फ़ाइल उत्पन्न की जा सकती है। यदि पाठ में अल्पविराम होता है, तो CSV से निपटने के लिए दर्द होता है, इसलिए मैं |बेहतर संस्करण का उपयोग करके सीमांकित फ़ाइलें उत्पन्न करता हूं । धन्यवाद!
शिव

3

यदि कोई सूची (स्ट्रिंग की) सूची में केवल कोई समाधान काम करता है

यदि आपके पास अपनी खुद की वस्तुओं की एक सामान्य सूची है जैसे सूची (कार की) जहां कार में एन गुण हैं, तो आपको प्रत्येक कार ऑब्जेक्ट के गुणइन्फो को लूप करना होगा।

यहां देखें: http://www.csharptocsharp.com/generate-csv-from-generic-list


1
क्या आप कक्षा के टोस्टरिंग को ओवरराइड नहीं कर सकते हैं और उपरोक्त विधियों का उपयोग कर सकते हैं?
गेब्रियल गुइमारेस

3

मुझे एक अच्छी सरल विस्तार विधि पसंद है

 public static string ToCsv(this List<string> itemList)
         {
             return string.Join(",", itemList);
         }

तब आप मूल सूची पर विधि को कॉल कर सकते हैं:

string CsvString = myList.ToCsv();

कुछ अन्य सुझावों की तुलना में क्लीनर और पढ़ने में आसान है।


2

String.Join के साथ समस्या यह है कि आप मूल्य में पहले से मौजूद अल्पविराम के मामले को नहीं संभाल रहे हैं। जब एक अल्पविराम मौजूद होता है तो आप उद्धरण में मूल्य को घेर लेते हैं और सभी मौजूदा उद्धरणों को दोहरे उद्धरणों से बदल देते हैं।

String.Join(",",{"this value has a , in it","This one doesn't", "This one , does"});

CSV मॉड्यूल देखें


2

CsvHelper लाइब्रेरी नुगेट में बहुत लोकप्रिय है। आप इसके लायक हैं, यार! https://github.com/JoshClose/CsvHelper/wiki/Basics

CsvHelper का उपयोग करना वास्तव में आसान है। यह डिफ़ॉल्ट सेटिंग्स सबसे आम परिदृश्यों के लिए सेटअप है।

यहाँ थोड़ा सेटअप डेटा है।

Actors.csv:

Id,FirstName,LastName  
1,Arnold,Schwarzenegger  
2,Matt,Damon  
3,Christian,Bale

Actor.cs (कस्टम वर्ग ऑब्जेक्ट जो अभिनेता का प्रतिनिधित्व करता है):

public class Actor
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

CsvReader का उपयोग करके CSV फ़ाइल पढ़ना:

var csv = new CsvReader( new StreamReader( "Actors.csv" ) );

var actorsList = csv.GetRecords ();

CSV फ़ाइल में लिखना।

using (var csv = new CsvWriter( new StreamWriter( "Actors.csv" ) )) 
{
    csv.WriteRecords( actorsList );
}

2

जो भी कारण के लिए, @AliUmair ने अपने उत्तर को संपादित करने के लिए वापस कर दिया, जो अपने कोड को ठीक करता है जो कि नहीं चलता है, इसलिए यहां वह कार्यशील संस्करण है जिसमें फ़ाइल पहुंच त्रुटि नहीं है और ठीक से अशक्त ऑब्जेक्ट प्रॉपर्टी वैल्यू को संभालता है:

/// <summary>
/// Creates the CSV from a generic list.
/// </summary>;
/// <typeparam name="T"></typeparam>;
/// <param name="list">The list.</param>;
/// <param name="csvNameWithExt">Name of CSV (w/ path) w/ file ext.</param>;
public static void CreateCSVFromGenericList<T>(List<T> list, string csvCompletePath)
{
    if (list == null || list.Count == 0) return;

    //get type from 0th member
    Type t = list[0].GetType();
    string newLine = Environment.NewLine;

    if (!Directory.Exists(Path.GetDirectoryName(csvCompletePath))) Directory.CreateDirectory(Path.GetDirectoryName(csvCompletePath));

    using (var sw = new StreamWriter(csvCompletePath))
    {
        //make a new instance of the class name we figured out to get its props
        object o = Activator.CreateInstance(t);
        //gets all properties
        PropertyInfo[] props = o.GetType().GetProperties();

        //foreach of the properties in class above, write out properties
        //this is the header row
        sw.Write(string.Join(",", props.Select(d => d.Name).ToArray()) + newLine);

        //this acts as datarow
        foreach (T item in list)
        {
            //this acts as datacolumn
            var row = string.Join(",", props.Select(d => $"\"{item.GetType().GetProperty(d.Name).GetValue(item, null)?.ToString()}\"")
                                                    .ToArray());
            sw.Write(row + newLine);

        }
    }
}

1

http://cc.davelozinski.com/c-sharp/the-fastest-way-to-read-and-process-text-files

इस वेबसाइट ने कुछ व्यापक परीक्षण किया कि बफर लेखक का उपयोग करके किसी फाइल में कैसे लिखा जाए, लाइन बाय लाइन पढ़ना सबसे अच्छा तरीका लगता है, स्ट्रिंग बिल्डर का उपयोग करना सबसे धीमा में से एक था।

मैं अपनी तकनीकों का उपयोग सामान लिखने के लिए बहुत अच्छी तरह से करता हूं ताकि यह अच्छी तरह से काम कर सके।


1

एक सामान्य उद्देश्य ToCsv () विस्तार विधि:

  • Int16 / 32/64 का समर्थन करता है, फ्लोट, डबल, दशमलव, और कुछ भी समर्थन ToString ()
  • वैकल्पिक कस्टम विभाजक में शामिल होते हैं
  • वैकल्पिक कस्टम चयनकर्ता
  • वैकल्पिक शून्य / खाली हैंडलिंग विनिर्देश (* ऑप्ट () ओवरलोड)

उपयोग के उदाहरण:

"123".ToCsv() // "1,2,3"
"123".ToCsv(", ") // "1, 2, 3"
new List<int> { 1, 2, 3 }.ToCsv() // "1,2,3"

new List<Tuple<int, string>> 
{ 
    Tuple.Create(1, "One"), 
    Tuple.Create(2, "Two") 
}
.ToCsv(t => t.Item2);  // "One,Two"

((string)null).ToCsv() // throws exception
((string)null).ToCsvOpt() // ""
((string)null).ToCsvOpt(ReturnNullCsv.WhenNull) // null

कार्यान्वयन

/// <summary>
/// Specifies when ToCsv() should return null.  Refer to ToCsv() for IEnumerable[T]
/// </summary>
public enum ReturnNullCsv
{
    /// <summary>
    /// Return String.Empty when the input list is null or empty.
    /// </summary>
    Never,

    /// <summary>
    /// Return null only if input list is null.  Return String.Empty if list is empty.
    /// </summary>
    WhenNull,

    /// <summary>
    /// Return null when the input list is null or empty
    /// </summary>
    WhenNullOrEmpty,

    /// <summary>
    /// Throw if the argument is null
    /// </summary>
    ThrowIfNull
}   

/// <summary>
/// Converts IEnumerable list of values to a comma separated string values.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="values">The values.</param>        
/// <param name="joinSeparator"></param>
/// <returns>System.String.</returns>
public static string ToCsv<T>(
    this IEnumerable<T> values,            
    string joinSeparator = ",")
{
    return ToCsvOpt<T>(values, null /*selector*/, ReturnNullCsv.ThrowIfNull, joinSeparator);
}

/// <summary>
/// Converts IEnumerable list of values to a comma separated string values.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="values">The values.</param>
/// <param name="selector">An optional selector</param>
/// <param name="joinSeparator"></param>
/// <returns>System.String.</returns>
public static string ToCsv<T>(
    this IEnumerable<T> values,
    Func<T, string> selector,            
    string joinSeparator = ",") 
{
    return ToCsvOpt<T>(values, selector, ReturnNullCsv.ThrowIfNull, joinSeparator);
}

/// <summary>
/// Converts IEnumerable list of values to a comma separated string values.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="values">The values.</param>
/// <param name="returnNullCsv">Return mode (refer to enum ReturnNullCsv).</param>
/// <param name="joinSeparator"></param>
/// <returns>System.String.</returns>
public static string ToCsvOpt<T>(
    this IEnumerable<T> values,
    ReturnNullCsv returnNullCsv = ReturnNullCsv.Never,
    string joinSeparator = ",")
{
    return ToCsvOpt<T>(values, null /*selector*/, returnNullCsv, joinSeparator);
}

/// <summary>
/// Converts IEnumerable list of values to a comma separated string values.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="values">The values.</param>
/// <param name="selector">An optional selector</param>
/// <param name="returnNullCsv">Return mode (refer to enum ReturnNullCsv).</param>
/// <param name="joinSeparator"></param>
/// <returns>System.String.</returns>
public static string ToCsvOpt<T>(
    this IEnumerable<T> values, 
    Func<T, string> selector,
    ReturnNullCsv returnNullCsv = ReturnNullCsv.Never,
    string joinSeparator = ",")
{
    switch (returnNullCsv)
    {
        case ReturnNullCsv.Never:
            if (!values.AnyOpt())
                return string.Empty;
            break;

        case ReturnNullCsv.WhenNull:
            if (values == null)
                return null;
            break;

        case ReturnNullCsv.WhenNullOrEmpty:
            if (!values.AnyOpt())
                return null;
            break;

        case ReturnNullCsv.ThrowIfNull:
            if (values == null)
                throw new ArgumentOutOfRangeException("ToCsvOpt was passed a null value with ReturnNullCsv = ThrowIfNull.");
            break;

        default:
            throw new ArgumentOutOfRangeException("returnNullCsv", returnNullCsv, "Out of range.");
    }

    if (selector == null)
    {
        if (typeof(T) == typeof(Int16) || 
            typeof(T) == typeof(Int32) || 
            typeof(T) == typeof(Int64))
        {                   
            selector = (v) => Convert.ToInt64(v).ToStringInvariant();
        }
        else if (typeof(T) == typeof(decimal))
        {
            selector = (v) => Convert.ToDecimal(v).ToStringInvariant();
        }
        else if (typeof(T) == typeof(float) ||
                typeof(T) == typeof(double))
        {
            selector = (v) => Convert.ToDouble(v).ToString(CultureInfo.InvariantCulture);
        }
        else
        {
            selector = (v) => v.ToString();
        }            
    }

    return String.Join(joinSeparator, values.Select(v => selector(v)));
}

public static string ToStringInvariantOpt(this Decimal? d)
{
    return d.HasValue ? d.Value.ToStringInvariant() : null;
}

public static string ToStringInvariant(this Decimal d)
{
    return d.ToString(CultureInfo.InvariantCulture);
}

public static string ToStringInvariantOpt(this Int64? l)
{
    return l.HasValue ? l.Value.ToStringInvariant() : null;
}

public static string ToStringInvariant(this Int64 l)
{
    return l.ToString(CultureInfo.InvariantCulture);
}

public static string ToStringInvariantOpt(this Int32? i)
{
    return i.HasValue ? i.Value.ToStringInvariant() : null;
}

public static string ToStringInvariant(this Int32 i)
{
    return i.ToString(CultureInfo.InvariantCulture);
}

public static string ToStringInvariantOpt(this Int16? i)
{
    return i.HasValue ? i.Value.ToStringInvariant() : null;
}

public static string ToStringInvariant(this Int16 i)
{
    return i.ToString(CultureInfo.InvariantCulture);
}

0

यहां मेरी एक्सटेंशन विधि है, यह सादगी के लिए एक स्ट्रिंग देता है लेकिन मेरा कार्यान्वयन डेटा झील के लिए फ़ाइल लिखता है।

यह किसी भी सीमांकक के लिए प्रदान करता है, स्ट्रिंग में उद्धरण जोड़ता है (मामले में वे सीमांकक होते हैं) और सौदे शून्य और रिक्त होंगे।

    /// <summary>
    /// A class to hold extension methods for C# Lists 
    /// </summary>
    public static class ListExtensions
    {
        /// <summary>
        /// Convert a list of Type T to a CSV
        /// </summary>
        /// <typeparam name="T">The type of the object held in the list</typeparam>
        /// <param name="items">The list of items to process</param>
        /// <param name="delimiter">Specify the delimiter, default is ,</param>
        /// <returns></returns>
        public static string ToCsv<T>(this List<T> items, string delimiter = ",")
        {
            Type itemType = typeof(T);
            var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(p => p.Name);

            var csv = new StringBuilder();

            // Write Headers
            csv.AppendLine(string.Join(delimiter, props.Select(p => p.Name)));

            // Write Rows
            foreach (var item in items)
            {
                // Write Fields
                csv.AppendLine(string.Join(delimiter, props.Select(p => GetCsvFieldasedOnValue(p, item))));
            }

            return csv.ToString();
        }

        /// <summary>
        /// Provide generic and specific handling of fields
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="p"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        private static object GetCsvFieldasedOnValue<T>(PropertyInfo p, T item)
        {
            string value = "";

            try
            {
                value = p.GetValue(item, null)?.ToString();
                if (value == null) return "NULL";  // Deal with nulls
                if (value.Trim().Length == 0) return ""; // Deal with spaces and blanks

                // Guard strings with "s, they may contain the delimiter!
                if (p.PropertyType == typeof(string))
                {
                    value = string.Format("\"{0}\"", value);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return value;
        }
    }

उपयोग:

 // Tab Delimited (TSV)
 var csv = MyList.ToCsv<MyClass>("\t");
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.