none
IFormatProvider doesn't really "provide" does it? RRS feed

  • Question

  • So,

    I've worked with more on the extensible side of Visual Studio.   IServiceProvider is designed in an identical fashion.  YOu call the method and provide a type, and if that type is available, the implementing object returns an instance of that type.  The Name being what it is, the resulting object should be  "service" of some sort.  Thus far in my experience this has been true.

    The same could be said for the CodeCOM "CodeDomProvider", which is the primary (only) way to get a specific language's "Generator", and which is how Visual Studio generates code for the forms or dataset designer, etc.

    THis provider is even more specific that it actually is expected to return an ICodeCompiler or ICodeGenerator based upon the request. 

    These two examples are of many, but most of the depiction is MOOT.  Because for all of these examples it is almost universal that you are writing at MINIMUM the CONSUMER side of the equation, if not BOTH. 

    You can implement the CodeDomProvider yourself, and instead of returning the same as the base class, you can implement other methods of providing the appropriate implementations.  Just as well you can write the implementation of the IServiceProvider, but typically in those situations you are also writing the consuming code, and if not you must allow for all possible type requests coming through if you don't want VS to break.

    But so far, the ONLY thing IFormatProvider exists for is to be implemented by CultureInfo (and it's subseqent related clases DateTimeFormatInfo & NumberFormInfo.)  That's it.  I cannot "write" the provider for Dates and Times in order to give to a ToString(), or String.Format(), or even for my own custom data format process which sometimes needs to have customized formatting for different data elements.

    For example, the XML Serialization of a DateTime (when local) is "yyyy-MM-ddTHH:mm:ss:fffffffzzzzzz"  which has absolutely nothing to do with any culture info whatsoever.  It's designed to serialize the data not worry about "human readable formatting".

    Now expand that model to more and more data types.  I'm performing some kind of serialization, doesn't matter what, but the end result must be displayable in a very specific format. 

    My only option in .Net is to custom format EVERY SINGLE PRIMITIVE TYPE.  I can't create an IFormatProvider where the simple idea of "IFormatter GetFormat(Type type)" exists.  IFormatter would of course have a method and a property.  the property being a "string" that could be used in a ToString() for those types that need it, or could be applied to a String.Format() format string.  the method, GetString() would take the type and return the formatted string for you.  Even ICustomFormatter ASSUMES the developer is going to provide the format string.  If it truly was an IFormatProvider it wouldn't just provide two customized format objects that are both sealed and thus not reusable in ANY fashion.

    Where is the functionality to provide the format for these objects in a late-binding fashion.

    ToCSV(object[][] values, IFormatProvider formats) 
    {
      StringBuilder sb = new StringBuilder(0x1000);
      for(int r=0;r<values.Length;r++) 
      {
        for(int c=0;c<values[r].Length;c++)
        {
          formatter = formats.GetFormat(values[r][c].GetType());
          if (formatter != null) 
          {
            if (formatter.HasFormat) sb.AppendFormat(formatter.FormatString, values[r][c]);
            else sb.Append(formatter.GetString(values[r][c]));
          }
          else sb.Append(values[r][c]);
          if (c > 0) sb.Append(",");
        }
        sb.Append(Environment.NewLine)
      }
    }

    It's a crude, simplistic example, but to me this is what a "Provider" should do especially when it is called IFormatProvider.

    Now, Bob can implement I format provider and have all Decimal types output like currency, and all floats have only 4 sig digs.  While Larry can output dates in a dd mmm yyyy format, while creating a custom interpretation for the System.Drawing.Size and Point structures.  All of this is encapsulated in a singular interface that provides formats for all data types, and if the type doesn't exist, it goes default.

    Granted as well, my above example is depicting a use case that I can (and have to a degree) implement manually.  However, the same IFormatProvider cannot be handed off to String.Format, or DateTime.ToString().  Well, it could but those systems wouldn't make any use of them.

    So, before I invest too much time in constructing own own system to handle this, does this functionality already exist in .Net?  Currently I'm using a hashtable to pass in type keys with format strings via a decorator pattern for string builder, but if another system does not exist I'll want to update this model.

    Thanks

    Jaeden "Sifo Dyas" al'Raec Ruiner

    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.

    Monday, July 27, 2015 4:41 PM

Answers

All replies

  • Hi Jaeden,

    >>So, before I invest too much time in constructing own own system to handle this, does this functionality already exist in .Net? 

    I am afraid, there is no class or method to implement directly in .Net Framework. You may wirte your logic by yourself.

    Please also refer to IFormatProvider Interface  from MSDN document for more detailed information.

    Best regards,

    Kristin


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, July 29, 2015 2:45 AM
  • CultureInfo is designed to drain the formatting settings from your Windows regional settings.

    If you need to create specific formatting, use classes like NumberFormatInfo, DateTimeFormatInfo, etc. because the formatting is going to be specific to your application.

    To set these for your current culture so you don't have to loop like what you've written, see the specific section on this topic. (In short, CultureAndRegionInfoBuilder is your friend.)

    EDIT: Note that you need Admin right to create a new culture so it may not be suit your need. Creating CultureInfo with useUserOverride = true, then replace members like .NumberFormat could be better approach for you.


    Wednesday, July 29, 2015 9:34 AM
    Answerer