Reputation: 48476
What would be the best way to accomplish something like this?
Suppose I have the following pair of Resource
strings.
BadRequestParameter: Potential bad request aborted before execution.
RequiredParameterConstraint: {0} parameter requires a value. {1}
And suppose I want to set {1}
on the second one, to the value of BadRequestParameter
. I could easily do that using string.Format
. But now suppose I have lots of Resource
strings like the second one, all of which include some other Resource
string in them.
What would be the best way to code this? Is using string.Format
repeateadly in each case really all that I can do?
Update
I'll try to explain myself better. These are the resource strings I actually have:
BadRequestParameter Potential bad request aborted before execution.
EmptyVector Vectorized requests require at least one element. {0}
OverflownVector Vectorized requests can take at most one hundred elements. {0}
RequiredParamConstraint {0} parameter requires a value. {1}
SortMinMaxConstraint {0} parameter value '{1}' does not allow Min or Max parameters in this query. {2}
SortRangeTypeConstraint Expected {0} parameter Type '{1}'. Actual: '{2}'. {3}
SortValueConstraint {0} parameter does not allow '{1}' as a value in this query. {2}
I'd like to avoid writing the string in BadRequestParameter
at the end of each of those lines. Therefore, I added a format at the end of those strings. The issue now is that I'd like to somehow auto-reference {x}
to BadRequestParameter
, in order to avoid having to make calls like
string.Format(Error.EmptyVector, Error.BadRequestParameter);
Upvotes: 4
Views: 1076
Reputation: 726579
I have lots of Resource strings like the second one, all of which include some other Resource string in them.
Instead of storing pre-made format strings ready for use, you could store raw material for building real format strings, and add code to expand them pro grammatically before use. For example, you could store strings like this:
BadRequestParameter: Potential bad request aborted before execution.
SupportNumber: (123)456-7890
CallTechSupport: You need to call technical support at {SupportNumber}.
RequiredParameterConstraint: {{0}} parameter requires a value. {BadRequestParameter} {CallTechSupport}
Of course passing these strings to string.Format
as-is is not going to work. You need to parse these strings, for example with RegExp
s, and find all instances where you have a word between curly braces, instead of a number. You could then replace each word with its sequence number, and produce an array of parameters based on the names that you find between curly braces. In this case, you will get these two values (pseudocode):
formatString = "{{0}} parameter requires a value. {0} {1}";
// You replaced {BadRequestParameter} with {0} and {CallTechSupport} with {1}
parameters = {
"Potential bad request aborted before execution."
, "You need to call technical support at (123)456-7890."
};
Note: Of course, producing this array of parameters
required recursion.
At this point, you can invoke string.Format
to produce your final string:
var res = string.Format(formatString, parameters);
This returns the string that has resource strings pre-replaced for your callers:
"{0} parameter requires a value. Potential bad request aborted before execution. You need to call technical support at (123)456-7890."
The callers can now use this string for formatting, without bothering with other resource values.
Upvotes: 1
Reputation: 15242
IF you treat the argument indicators {#}
as wild cards then why would it make sense for you to pre-fill them inside of your resource.
I see absolutely nothing wrong with
String.Format(RequiredParamterConstraint, "something", BadRequestParameter);
Upvotes: 0
Reputation: 47749
Yes :-) unless you want to make a helper method that is shorter, but that would really just be for convenience sake
public static string f(string format, params object[] p)
{
return string.Format(format, p);
}
Upvotes: 0