1

For this specific need, I have two const strings containing parameters, like this:

private const string myString = "The operation #{0} has been completed successfully in {1} seconds";

This type of constant is of course used with String.Format() later on, in order to generate feedback messages.

Now I am facing a specific case, where I have those two constants. My example is not the real case, for privacy purposes, so it doesn't look very useful or even logical, but I assure you the real thing makes sense in context. I just couldn't get a good idea for a fake case with the same problem:

private const string shortFormat = "operation {0} out of {1}";
private const string longFormat = "During step one, an error was encountered on operation {0} out of {1}, and during step two, an error was encountered on operation {2} out of {3}";

You can see an obvious redundancy here. One of the constants is used twice Inside the second one for literally the same purpose, just in a bigger picture.

If it was used only once, I could re-use it like this:

private const string shortFormat = "operation {0} out of {1}";
private const string longFormat = "During step one, an error was encountered on " + shortFormat + " so the process has not completed step two.";

This would look much better. But I don't know how to use it twice like in the first example. If I simply insert shrotFormat twice, then I will duplicate parameters 0 and 1, so the string at runtime will look like this:

"During step one, an error was encountered on operation {0} out of {1}, and during step two, an error was encountered on operation {0} out of {1}"

Which obviously will not work with 4 different parameters in string.Format()

How can I make this not repeat itself, while keeping all four parameter numbers different and useable with 4 values?

4
  • The runtime string doesn't match the value in longFormat...Where did this runtime string come from? And why can't you just call String.Format on each use of the shortFormat constant? private const string runtimeText = "During step one, an error was encountered on " + string.Format(shortFormat, stepOneErrorOperation, stepOneTotalOperations) + ", and during step two, an error was encountered on " + string.Format(shortFormat, stepTwoErrorOperation, stepTwoTotalOperations) + "." Commented May 7, 2018 at 19:22
  • 2
    I like the concept but combining constants as future combined const formats wouldn't be considered good practice and this may be one of the reasons why. Instead of reducing complications and saving resources I feel that you're over engineering it with good intentions. Strings are immutable so don't be afraid to duplicate some of the text for long string and or remove formatting in all but long string. Commented May 7, 2018 at 19:35
  • @LewsTherin Because string.Format(), as a function, can't be used in the declaration of a constant Commented May 8, 2018 at 11:24
  • @KaitoKid Splitting hairs. Make them readonly instead and do the initialization in the constructor. My point still stands. Commented May 8, 2018 at 15:44

1 Answer 1

5

You could use string.Format multiple times:

private const string stepFormat= "operation {0} out of {1}";
private const string twoStepMessage = "During step one, an error was encountered on {0}, and during step two, an error was encountered on {1}";

public string CreateMessage(int s1, int s1total, int s2, int s2total)
{
    string stepOne = string.Format(stepFormat, s1, s1total);
    string stepTwo = string.Format(stepFormat, s2, s2total);
    return string.Format(twoStepMessage, stepOne, stepTwo);
}

Of course this requires the calling code to have knowledge of the structure of the message, as it cannot simply provide the values blindly to a single format.

Sign up to request clarification or add additional context in comments.

2 Comments

I agree that this would work. On the other hand, my problem specifically resides in the fact that I would like to have this "formattable" string as a constant. If this requirement disappears, which will have to happen if no solution is found that fulfills it, then there are hundreds of ways to make this work at runtime. I'm looking for a clean way to make this into the constants without any redundancy. If this is impossible, then an answer explaining/proving this would be accepted.
You can't "solve" the problem inside the constants, so it'd require a change in code somewhere - it would be easy to write a library/helper/extension that performs string.Format on non-numbered placeholders, ie: "First value is @ and second is @". You'd lose the possibility to change the order of the placehoders, though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.