2009-11-08 10 views
30

का उपयोग कब करें IFormattable, IFormatProvider और ICustomFormatter के बीच अंतर और कनेक्शन क्या हैं और उनका उपयोग कब किया जाएगा? एक सरल कार्यान्वयन उदाहरण भी बहुत अच्छा होगा।सी #: IFormattable, IFormatProvider और ICustomFormatter के बीच कनेक्शन, और

और मैं वास्तव में जब यह .net ढांचे में प्रयोग किया जाता है इसका मतलब यह नहीं है, लेकिन जब मैं इन अपने आप को लागू करेगा और उस मामले में क्या कक्षाएं आम तौर पर क्या इंटरफेस और कैसे इसे ठीक करने के लिए लागू होगा।

उत्तर

32
  • IFormattable एक वस्तु जो string.Format में स्वरूपों का समर्थन करता है, यानी {0:xxx} में xxx है: मैं गलत एक IFormattable वस्तु का एक उदाहरण हो सकता है ...

    । यदि ऑब्जेक्ट इंटरफ़ेस का समर्थन करता है तो string.Format ऑब्जेक्ट की IFormattable.ToString विधि में प्रतिनिधि होगा।

  • IFormatProvider कॉन्फ़िगरेशन जानकारी का एक स्रोत है जो स्वरूपक संस्कृति-विशिष्ट दिनांक और मुद्रा लेआउट जैसी चीज़ों के लिए उपयोग करते हैं।

  • हालांकि, जैसे इस तरह की स्थितियों के लिए DateTime, जहां आप जिस प्रारूप को प्रारूपित करना चाहते हैं वह पहले से ही IFormattable लागू करता है, फिर भी आप कार्यान्वयन को नियंत्रित नहीं करते हैं (DateTime बीसीएल में आपूर्ति की जाती है, आप इसे आसानी से प्रतिस्थापित नहीं कर सकते हैं), का उपयोग करके string.Format को रोकने के लिए एक तंत्र है। इसके बजाय, आप IFormatProvider लागू करते हैं, और जब ICustomFormatter कार्यान्वयन के लिए कहा जाता है, तो एक लौटाएं। string.Format चेकों एक ICustomFormatter के लिए प्रदाता से पहले ही वस्तु की IFormattable.Format के प्रतिनिधियों, जो बारी में होने की संभावना CultureInfo की तरह संस्कृति-विशिष्ट डेटा के लिए IFormatProvider पूछना होगा।

यहाँ एक प्रोग्राम है जो बताती है कि किन string.Format पूछता है के लिए IFormatProvider है, और कैसे नियंत्रण के प्रवाह जाता है:

Asked for System.ICustomFormatter 
ToString("foobar", provider) called 
arbitrary value 

तो प्रारूप प्रदाता:

using System; 
using System.Globalization; 

class MyCustomObject : IFormattable 
{ 
    public string ToString(string format, IFormatProvider provider) 
    { 
     Console.WriteLine("ToString(\"{0}\", provider) called", format); 
     return "arbitrary value"; 
    } 
} 

class MyFormatProvider : IFormatProvider 
{ 
    public object GetFormat(Type formatType) 
    { 
     Console.WriteLine("Asked for {0}", formatType); 
     return CultureInfo.CurrentCulture.GetFormat(formatType); 
    } 
} 

class App 
{ 
    static void Main() 
    { 
     Console.WriteLine(
      string.Format(new MyFormatProvider(), "{0:foobar}", 
       new MyCustomObject())); 
    } 
} 

यह इस प्रिंट एक कस्टम फॉर्मेटर वापस करने के लिए बदला जाता है, यह लेता है:

class MyFormatProvider : IFormatProvider 
{ 
    public object GetFormat(Type formatType) 
    { 
     Console.WriteLine("Asked for {0}", formatType); 
     if (formatType == typeof(ICustomFormatter)) 
      return new MyCustomFormatter(); 
     return CultureInfo.CurrentCulture.GetFormat(formatType); 
    } 
} 

class MyCustomFormatter : ICustomFormatter 
{ 
    public string Format(string format, object arg, IFormatProvider provider) 
    { 
     return string.Format("(format was \"{0}\")", format); 
    } 
} 

जब रन:

Asked for System.ICustomFormatter 
(format was "foobar") 
+0

आप 'MyFormatProvider.GetFormat' में' CultureInfo.CurrentCulture.GetFormat' क्यों लौटते हैं? और 'MyCustomFormatter.Format' में' IFormatProvider' का उपयोग आप क्या करेंगे? – Svish

+0

डिफ़ॉल्ट प्रारूप प्रदाता CultureInfo.CurrentCulture है; यह वह है जिसका उपयोग किया जाता है यदि आप 'स्ट्रिंग.फॉर्मैट' में ओवरलोड में से किसी एक में निर्दिष्ट नहीं करते हैं। मैंने पहले ही समझाया है कि आप IFormatProvider का उपयोग क्यों करेंगे - कॉन्फ़िगरेशन जानकारी प्रदान करने के लिए (उदा। संस्कृतिइन्फो के लिए पूछें), दिनांक स्वरूपण जैसी चीजों के लिए (उदाहरण के लिए CultureInfo.DateTimeFormat का उपयोग करने के लिए)। –

1

IFormattable एक ऑब्जेक्ट है जो अलग-अलग (नामित/कस्टम) प्रारूपों का समर्थन करता है - उदाहरण के लिए, संख्याएं, आदि। इंटरफ़ेस का उपयोग करके, कोड के एकाधिक ब्लॉक मान और प्रारूप स्ट्रिंग का उपयोग कर सकते हैं, और यह सामान्य है (उदाहरण के लिए) डेटा बाध्यकारी और string.Format में। विशेष रूप से i18n -

एक IFormatProvider कुछ स्वरूपण के साथ काम कर कमियों को पूरा करता। आमतौर पर, CultureInfo प्रदाता के रूप में उपयोग किया जाता है, या तो एक विशिष्ट स्थानीय प्रारूप, या परिवर्तनीय संस्कृति प्रदान करता है।

जहाँ तक मुझे पता है, ICustomFormatter असंबंधित है, और serialization (BinaryFormatter) में और अधिक संबंध है।

IFormattable d = 123.45M; 
string s1 = d.ToString("c", CultureInfo.CurrentCulture), // local currency 
     s2 = d.ToString("c", CultureInfo.InvariantCulture); // invariant currency 
+2

यह एक बहुत पुरानी जवाब है, लेकिन बच्चों की खातिर: 'ICustomFormatter' के बारे में स्ट्रिंग स्वरूपण, और कहा कि' नहीं हैं प्रकार के प्रारूप स्ट्रिंग्स के लिए समर्थन जोड़ने के लिए वास्तव में है IFormattable 'कार्यान्वयन (या 'IFormattable' ऑब्जेक्ट्स के लिए अलग प्रारूप स्ट्रिंग प्रदान करने के लिए)। 'IFormatter' serialization के बारे में एक है। –

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