1

Is there a format string for the C# string.Format method that picks a substring from the corresponding argument? Like so:

var lang1 = "EN";
var lang2 = "FR";

var shortFormat = "Foo-{0:0-0}.pdf";
var longFormat = "Foo-{0:0-1}.pdf";

string.Format(shortFormat, lang1) // Foo-E.pdf
string.Format(shortFormat, lang2) // Foo-F.pdf
string.Format(longFormat, lang1) // Foo-EN.pdf
string.Format(longFormat, lang2) // Foo-FR.pdf

To anticipate a few comments: Yes, I know the Substring method. I have also read that string.Format is slower than a simple Substring. The example above is heavily simplified. Imagine that the string.Format statement resides in one place, while the lang1/lang2 argument is an input from another place and the shortFormat/longFormat is defined in a resx file.

That is, in the place where the format is to be defined we don't know anything about the value being formatted (lang1/lang2 in the example) nor do we have any means to execute C# code. Hence we can't call any method such as Substring on the value. At the place where the formatting code runs, in turn, we take the format as a parameter, so we can't simply perform a Substring on the value because we don't know whether the format requires it or not (except if we inspect the format).

chiccodoro
  • 14,407
  • 19
  • 87
  • 130

3 Answers3

0

No, the string.Format does not have this feature, which is better explained here: Can maximum number of characters be defined in C# format strings like in C printf?

If you don't want to use Substring I would create an extension class for string like this: http://msdn.microsoft.com/en-us/library/bb311042.aspx

namespace CustomExtensions
{
    public static class StringExtension
    {
        public static string ShortFormat(this string str)
        {
            // manipulate and return str here
        }
        public static string LongFormat(this string str)
        {
            // manipulate and return str here
        }
    }
}
Community
  • 1
  • 1
Niklas
  • 13,005
  • 23
  • 79
  • 119
  • Thank you for the answer. I was afraid of that. As for the suggestion with the extension methods - I think this still would not solve my issue, as I mentioned in my "anticipate" part: In the place where the format is defined (e.g. in a resx file), the value is not known. That's why it can't be accessed either for a `Substring` or for any extension methods on it. – chiccodoro Apr 03 '14 at 08:59
  • Oh, ok. Pretty difficult then =/ – Niklas Apr 03 '14 at 09:13
0

XSLT formatting can be an option: user gets ability to provide almost everything in configuration file and even execute custom c# code in your domain if it is required.

Please also consider that changes of format can be restricted to relatively small amount of actions: crop, pad or insert one or two things in some positions. Each one can be set as individual function and provided with own parameters.

Community
  • 1
  • 1
Grigoriy
  • 1
  • 1
0

There are two ways to provide custom formatting. You can either implement IFormattable on a custom type to control how that type is always formatted, or implement IFormatProvider to override how other types are formatted in specific cases.

In your case I would suggest creating a new type to encapsulate how your software deals with language codes;

public struct LanguageCode : IFormattable {
   public readonly string Code;
   public LanguageCode(string code) {
      Code = code;
   }

   public override string ToString()
      => this.ToString("L", CultureInfo.CurrentCulture);
   public string ToString(string format)
      => this.ToString(format, CultureInfo.CurrentCulture);

   public string ToString(string format, IFormatProvider provider){
      if (String.IsNullOrEmpty(format))
         format = "L";
      if (provider == null)
         provider = CultureInfo.CurrentCulture;
      switch (format.ToUpperInvariant()){
         case "L": // Long
            return Code.ToString(provider);
         case "S": // Short
            return Code.SubString(0,1).ToString(provider);
         default:
            throw new FormatException($"The {format} format string is not supported.");
      }
   }

   public static implicit operator LanguageCode(string code)
      => new LanguageCode(code);
   public static implicit operator string(LanguageCode language)
      => language.Code;
}

Then from your example;

   var lang1 = (LanguageCode)"EN";
   LanguageCode lang2 = "FR";

   var shortFormat = "Foo-{0:S}.pdf";
   var longFormat = "Foo-{0:L}.pdf";
Jeremy Lakeman
  • 9,515
  • 25
  • 29