2013-07-12 13 views
6

मेरे पास है:String.Format विस्तार विधि

public static string Format(this string text, params object[] args) 
{ 
    return string.Format(text, args); 
} 

तो मैं कर सकते हैं:

"blablabla {0}".Format(variable1); 

यह एक अच्छा/बुरा है? क्या यह भी छोटा हो सकता है? मैं तार, मूल निर्माण में चिंता किए बिना पाठ लिखने की तरह करना चाहते हैं पहले या मापदंडों और सामान के बाद:

// bad 
return "date: " + DateTime.Now.ToString("dd.MM.yyyy") + "\ntime: " + DateTime.Now.ToString("mm:HH:ss") + "\nuser: " + _user + " (" + _status + ")"; 

// better, but you have to deal with order of {0}...{n} and order of parameters 
return string.Format("date: {0}\ntime: {1}\user: {2} ({3})", ...); 

// ideal 
return "date: {DateTime.Now{dd:MM:yyyy}}\ntime: {...}\nuser: {_user} ({_status})"; 
+0

मुझे इस विचार की अपेक्षित आउटपुट बहुत भ्रमित लगता है। – Steve

+0

"क्या यह एक अच्छा/बुरा है?": आप राय के लिए पूछ रहे हैं जो [SO] पर विषय से बाहर है। – Richard

+0

@ रिचर्ड, यह उन लोगों में से केवल एक प्रश्न है जो मैंने पूछा = पी – Sinatr

उत्तर

3

ठीक है, एक बुरा बात नहीं है केवल एक ही params object[] विधि होने से आप एक अतिरिक्त बल सरणी आवंटन प्रति कॉल।

आप देख सकते हैं कि string.Format में कम संख्या में तर्क लेने के लिए ओवरलोड हैं (इनका उपयोग आमतौर पर किया जाता है) - मैं उन्हें डुप्लिकेट करने का सुझाव दूंगा।

आपका 'आदर्श' परिदृश्य string.Format विधि को फिर से लिखकर द्वारा किया जा सकता है, लेकिन आप

return "date: {date}\ntime: {...}\nuser: {_user} ({_status})" 
    .Format(new { date = DateTime.Now, _user, _status }); 

मूल्यों में पारित करने के लिए, यानी आवश्यकता होगी (और अपने स्वयं के कस्टम Format पद्धति का उपयोग करके, या one like this) - लेकिन ध्यान दें कि यह प्रति कॉल एक नया ऑब्जेक्ट उदाहरण देता है।

वास्तव में, एक बिंदु पर मोनो कंपाइलर के पास इसे सीधे सक्षम करने के लिए एक प्रयोगात्मक ध्वज था। मुझे नहीं पता कि यह बनाए रखा गया है या नहीं।

+0

मेरे पहचानकर्ताओं को एक स्ट्रिंग में डालने के बारे में कूल विचार और फिर उन्हें आवश्यक मूल्यों के साथ प्रतिस्थापित करें। धन्यवाद! – Sinatr

1

यह निर्भर करता है कि आप अकेले कोडिंग कर रहे हैं या कोई टीम है। एक टीम में यह एक बहुत बुरा विचार है क्योंकि हर किसी को इस विधि को सीखना होगा।

एक और समस्या स्ट्रिंग्स पर तर्क के साथ प्रारूप में है जो गलती से {2} की बजाय गलत इंडेक्स जैसे {1} के साथ ब्रेसिज़ रखती है। इस तरह बस खराब स्ट्रिंग पूरे एप्लिकेशन को दुर्घटनाग्रस्त कर देगी। मैंने अपने लॉगिंग के लिए कुछ ऐसा ही इस्तेमाल किया और FormatExceptions के लिए प्रयास-पकड़ का उपयोग करना पड़ा।

+0

यदि मैं विस्तार विधि के अंदर प्रयास/पकड़ डालता हूं और प्रोग्रामिंग गलतियों के बारे में सिग्नल करने के लिए कुछ अन्य तरीका प्रदान करता हूं (उदाहरण के लिए, स्ट्रिंग के अंत में जोड़कर "ओमजी, पैरामीटर {10} गायब है"), तो एक्सटेंशन विधि एक है बड़ा फायदा (इसलिए मुझे हर प्रारूप के लिए कोशिश/पकड़ डुप्लिकेट करने की आवश्यकता नहीं है)। और प्रत्येक टीम के पास आम मामलों के लिए अपना "स्टाइल" या सामान्य समाधान होता है। यदि आप वाक्यविन्यास से भ्रमित हो जाएंगे - तो आप तुरंत देख सकते हैं कि यह विजुअल स्टूडियो में सीधे क्या है। तो मुझे यहां एक बड़ी समस्या नहीं दिख रही है। – Sinatr

2

मैं भी इसी तरह की विस्तार विधि का उपयोग करता हूं, और मुझे यह पसंद है, मैं अपने मामले में सिस्टम के लिए तय की गई विस्तार विधि में संस्कृति जानकारी भी निर्दिष्ट करता हूं।

public static string Format(this string formatTemplate, params object[] args) 
{ 
    return string.Format(SysSettings.CultureInfo, formatTemplate, args); 
} 

Usages:

return "date: {0:dd.MM.yyyy}\ntime: {1:mm:HH:ss}\nuser: {2} ({3})".Format(DateTime.Now, DateTime.Now, _user, _status); 
+0

संस्कृति के साथ बहुत बढ़िया विचार, धन्यवाद। मुझे 'डबल' या 'फ्लोट' का उपयोग करते समय दशमलव बिंदु के लिए तटस्थ संस्कृति का उपयोग करने के लिए धक्का दिया गया था और कभी भी 'int' का उपयोग करते समय, और विस्तार विधि के साथ मैं 1 शूट में सबकुछ मार सकता हूं! – Sinatr

+0

यह एक संकलन त्रुटि देगा यदि आप पहले स्ट्रिंग होने के साथ 2 तर्कों को पारित करने का प्रयास करते हैं। '" {0} - {1} "प्रारूप (" उदाहरण ", 1); 'क्योंकि यह – GP89

3

यह काफी अपने आदर्श से मेल नहीं खाता है, लेकिन कुछ इस तरह आप के लिए काम कर सकते हैं:

public static class Extensions 
{ 
    public static string Format(this object data, string format) 
    { 
     var values = new List<object>(); 
     var type = data.GetType(); 
     format = Regex.Replace(format, @"(^|[^{])\{([^{}]+)\}([^}]|$)", x => 
     { 
      var keyValues = Regex.Split(x.Groups[2].Value, 
             "^([^:]+):?(.*)$") 
            .Where(y => !string.IsNullOrEmpty(y)); 

      var key = keyValues.ElementAt(0); 
      var valueFormat = keyValues.Count() > 1 ? 
           ":" + keyValues.ElementAt(1) : 
           string.Empty; 


      var value = GetValue(key, data, type); 

      values.Add(value); 
      return string.Format("{0}{{{1}{2}}}{3}", 
            x.Groups[1].Value, 
            values.Count - 1, 
            valueFormat, 
            x.Groups[3].Value); 
     }); 


     return string.Format(format, values.ToArray()); 
    } 

    private static object GetValue(string name, object data, Type type) 
    { 
     var info = type.GetProperty(name); 
     return info.GetValue(data, new object[0]); 
    } 
} 

यह आपको इस तरह की ऐसा करने की अनुमति चाहिए किसी ऑब्जेक्ट पर स्वरूपण:

new {Person = "Me", Location = "On holiday"} 
    .Format("{Person} is currently {Location}"); 

यह आपको कुछ स्वरूपण जोड़ने की भी अनुमति देगा:

new {Person = "Me", Until = new DateTime(2013,8,1)} 
    .Format("{Person} is away until {Until:yyyy-MM-dd}); 

यह आपके लिए कैसा है? मुझे यकीन है कि दक्षता के मामले में कोड में सुधार किया जा सकता है लेकिन यह काम करता है!

+0

एक्सटेंशन के बजाय स्ट्रिंग.फॉर्मैट स्थैतिक हस्ताक्षर से मेल खाता है। आपका विचार तर्क के पहले * एआर * उत्पन्न करना है * '{0}' की बजाय प्रारूप स्ट्रिंग में वैरिएबल का * name * डालने के लिए, जो मुझे लगता है कि अच्छा है। धन्यवाद। – Sinatr

+0

हां, स्वरूप एक्सटेंशन विधि को छोड़कर किसी ऑब्जेक्ट की बजाय ऑब्जेक्ट पर कॉल किया जाता है। मेरे उदाहरणों में यह एक अज्ञात प्रकार का उदाहरण है, लेकिन वास्तव में यह कोई ऑब्जेक्ट हो सकता है, जैसे डोमेन ऑब्जेक्ट: (उदाहरण: var person = new Person ("Aaron", "Janes"); person.Format ("{ LastName}, {FirstName} ");) –

+0

वर्तमान में विस्तारित एक्सटेंशन विधि अनुक्रमित गुणों का समर्थन नहीं करती है: नया {आइटम = नया [] {" एक "," दो "}}। फार्मेट (" पहला आइटम: { आइटम [0]} "); काम नहीं करेगा। हालांकि यह सूचकांक के लिए समर्थन जोड़ने के लिए अपेक्षाकृत मामूली होना चाहिए। –

संबंधित मुद्दे