Click here to Skip to main content
Click here to Skip to main content

StringFormat Methods with string keys

By , 17 Jan 2011
 
Introduction
 
System.String type gives us a very useful 'Format' method, that replaces one or more format items (keys) in a specified string with the concrete values. The method determines necessary value by its position in arguments set.
So, if the format string is short or number of format items is few, we can easily control the correspondence between keys in 'format' string and values in arguments set. But if the string is too large and number of arguments is great, we can be confused in arguments order.
 
Body
 
Two methods that use names as a keys in 'format' string are presented here. If we use names as keys, and Name-Value pairs as arguments, the confusion probability is reduced.
 
First, we define NamedValue class that contains a name and a value of the argument.
    public class NamedValue {
        private string _name = "";
        public string Name {
            get { return _name; }
            set {
                if (value == null || value.Trim() == "") {
                    throw new ArgumentException();
                }
                _name = value.Trim();
            }
        }
        private object _value = null;
        public object Value {
            get { return _value; }
            set { _value = value; }
        }
        public NamedValue() { }
        public NamedValue(string name, object value) {
            Name = name;
            Value = value;
        }
    }
Next static class StringFormat contains methods, CreateSimpleNamedFormat and CreateNamedFormat. First argument of each method is format string, next is a set of arguments of NamedValue class, almost like in native 'Format'. The functions replace all occurrences of embraced keys in 'format' string by its values. It gets value from the property Value of correspondence NamedValue instance in arguments set.
    public static class StringFormat {
        /// <summary>
        /// Replaces the format item in a specified System.String with the text equivalent
        ///     of the value of a corresponding NamedValue.Value instance in a specified array.
        /// This method doesn't support modifiers.
        /// </summary>
        /// <param name="stringBuilder"></param>
        /// <param name="format">Represents formatted string, where keys are embraced names.</param>
        /// <param name="args">Arguments that replaces keys in the 'format' string.</param>
        /// <exception cref="">FormatException</exception>
        public static string CreateSimpleNamedFormat(string format, params NamedValue[] args) {
            for (int i = 0; i < args.Length; i++) {
                format = format.Replace("{" + args[i].Name + "}", args[i].Value.ToString());
            }
            return format;
        }
        /// <summary>
        /// Replaces the format item in a specified System.String with the text equivalent
        ///     of the value of a corresponding NamedValue.Value instance in a specified array.
        /// This method fully supports modifiers.
        /// </summary>
        /// <param name="stringBuilder"></param>
        /// <param name="format">Represents formatted string, where keys are embraced names with, possibly, modifiers.</param>
        /// <param name="args">Arguments that replaces keys in the 'format' string.</param>
        /// <exception cref="">FormatException</exception>
        public static string CreateNamedFormat(string format, params NamedValue[] args) {
            List<object> argsValues = new List<object>();
            for (int i = 0; i < args.Length; i++) {
                NamedValue curArg = args[i];
                format = format.Replace("{" + curArg.Name + "}", "{" + i.ToString() + "}");
                format = format.Replace("{" + curArg.Name + ":", "{" + i.ToString() + ":");
                argsValues.Add(curArg.Value);
            }
            return string.Format(format, argsValues.ToArray());
        }
    }
Method 'CreateSimpleNamedFormat' doesn't support modifiers. But method 'CreateNamedFormat' fully supports it. I create two methods intentionally, because their performance differs considerably.
C# 4.0 get us the good feature of extension methods. And we can now easily realize two extension methods for StringBuilder.
    public static class StringBuilderExtensions {
        public static void AppendSimpleNamedFormat(this StringBuilder stringBuilder, string format, params NamedValue[] args) {
            stringBuilder.Append(StringFormat.CreateSimpleNamedFormat(format, args));
        }
        public static void AppendNamedFormat(this StringBuilder stringBuilder, string format, params NamedValue[] args) {
            stringBuilder.Append(StringFormat.CreateNamedFormat(format, args));
        }
    }
 
Conclusion
 
Presented methods are very simple. It needs to perform arguments verification and some other tests. In the article, I wanted only to share my idea. I hope this article helps you in your work.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Maksmax

Russian Federation Russian Federation
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralReason for my vote of 4 As you say, would all but eliminate ...memberdmjm-h24-Jan-11 10:48 
Reason for my vote of 4
As you say, would all but eliminate the hard-to-detect error of mis-ordering arguments in a long list.
GeneralReason for my vote of 5 Nice!mvpManfred R. Bihy17-Jan-11 12:06 
Reason for my vote of 5
Nice!
GeneralReason for my vote of 1 If the set of arguments within your ...memberervegter17-Jan-11 1:14 
Reason for my vote of 1
If the set of arguments within your string.Format method grows large, it is a clear indication you're doing something wrong. You should refactor your code in cases like that.
GeneralRe: I'm now working at the simulation application. So, I have ma...memberMaksmax17-Jan-11 4:46 
I'm now working at the simulation application. So, I have many patterns. Pattern is a code on GPSS World language presented as @string. Some patterns contains 20 and over lines of code, and about 10 parameters. It was very easy to me to create patterns as multiline strings with named parameters.
GeneralRe: String.Format wasn't supposed to do mailmerges, but having a...memberEddy Vluggen19-Jan-11 0:45 
String.Format wasn't supposed to do mailmerges, but having a lot of fields in a large body of text isn't neccesarily an indication that you're doing something wrong. Even if I drop that argument completely, having a named field adds to the readability (and thus, maintainability) of the project.
GeneralReason for my vote of 5 nice piece of codememberPranay Rana17-Jan-11 0:40 
Reason for my vote of 5
nice piece of code

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130617.1 | Last Updated 17 Jan 2011
Article Copyright 2011 by Maksmax
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid