Should I use string.Contains() before string.Replace()? - c#

Is it unnecessary to have this if statement before doing a string replace?
if (myString.Contains(oldValue))
{
myString = myString.Replace(oldValue, newValue);
}

All the details are in the documentation for String.Replace:
Return Value:
A string that is equivalent to the current string except that all instances of oldValue are replaced with newValue. If oldValue is not found in the current instance, the method returns the current instance unchanged.
The if statement is not required.
An if statement is not even a performance optimization, since String.Replace returns the same object instance, if oldValue is not found. I have verified this using the following code:
namespace StringReplaceTest
{
class Program
{
static void Main(string[] args)
{
string s = "Test";
string s2 = s.Replace("Foo", "Bar");
string s3 = s.Replace("es", "tt");
}
}
}
Using the handy Make Object ID feature (right-click on a symbol in the Locals, Auto, or Watch window; see Common Expression Evaluator Features for more details) produced the following output:
s | "Test" {$1}
s2 | "Test" {$1}
s3 | "Tttt" {$2}

Since the String.Replace() function doesn't throw an exception if the string doesn't contain the value specified, it's unnecessary to verify it. It will go through an unnecessary condition.

I know this is an old thread, but just wanted to provide my 2ยข!
Please, let me know if what I'm saying is wrong, but I just tried it on my environment and seemed plausible! :)
For the most part, yes, the replace function will do the contains for you therefore it's unnecessary to have it separately. However, it is advantageous to do so if your "new value" is derived from a method - depending on how much work is done to get that value within the method!
Example when it not advantageous:
I'm working on making "String Replacers" for the body of an email sent by an application. For example, if the user has "[[User Name]]" within the body of the email, I want to replace that with the recipients first name. Thankfully, our framework has that information stored in memory, so I don't mind doing a single replace for that.
Example when it is advantageous:
Under the same premise from above, another replacer is "[[Payments]]". This would go to the database, and bring up a log of the top 1000 transactions the user made, then do some work on the data retrieved and show details on the body of the email. Imagine having to do all of that every time the user sends an email from the app, even if it doesn't contain the "[[Payments]]" keyword! Having the contains before calling my method that comes up with the string value of "[[Payments]]" really pays off here!
Long story short, it depends on your implementation, but for the most part - yes, it's unnecessary.

In me experience, if you will replace many time (and you need one replace) better checking with Contains(). In my case is help my code be more fast (almost doubled).

Related

C# read and react to a text string

assume that there is a string named "message", and assume an user type in the console,
"!My FB List", but words "FB" and "List" could be change. But "!My" won't change. So, I want to save the text the user type. Only if user used "!My" before the other words.
So, I don't know how to get this to 'if' command. Plz help me.
if (message == "!My "
Do you mean something like this?
if (message.StartsWith("!My "))
{
// do something
}
This code works in most situations. However, if you need to resolve situations like Kshitij Mehta mentioned in the comments, you'd be probably better off with a Split method parsing the string and comparing the first object of the array to the required string.
When you've split the input string into an array, you will just compare strings in a typical fashion (==), probably no need for fancy methods in that scenario.
One more "however" to consider - if your input string is long, splitting might not be the best idea to do. In that case I'd probably use regular expressions to compare the beginning of the inputted string.
The implementation depends on your needs. Just pick what suits you the best :)
It sounds like you want to accept commands and then do specific things based on those commands. Apparently, the "command" is the first word in the text typed by the user.
Thus, I'd split the message at whitespace and then switch for the first word:
var words = message.Split();
var command = words[0];
switch (command) {
case "!My":
// Do something
...
break;
case "!SomethingElse":
// Do something else
...
break;
...
}
Afterwards, you can use words[1] to get "FB" and words[2] to get "list". Be sure to use words.Length to verify if the required number of parameters has been specified before trying to access them.
String class includes many static methods, among which is StartsWith().
so your if statement can simply be
if(UserString.StartsWith("!My"))
{
// other conditional code here
}
It is not clear from your question whether you want to include cases where the user types "!My" before typing anything else, but he/she does NOT type a space immediately after typing !My.
If you only want to process the code if the three characters "!My" were followed by a space, then, (as suggested by #Walther), add a space to the test string in the StartsWith() method
if(UserString.StartsWith("!My "))
{
// other conditional code here
}

Trimming strings between two points

I have a string as follows:
ListViewSubItem: {Debian6/Debian6.vmx }
What would be the most efficient way of getting the following output:
Debian6/Debian6.vmx
int beginidx = haystack.IndexOf('{');
string needle = haystack.SubString(beginidx,
haystack.IndexOf('}') - beginidx + 1).Trim();
string result = Regex.Match("ListViewSubItem: {Debian6/Debian6.vmx }", #"(?<={)(.+?)(?=})").Value;
You can use a regex:
\{\s*(.*)\s*\}
The desired string will be in the first captured group (Match.Groups[1]).
Example:
string output = Regex.Match(input, #"\{\s*(.*?)\s*\}").Groups[1].Value;
As was pointed out, regexes are slower than plain string manipulation. If performance is an issue, and the string extraction is in a tight loop, then it may be better to use an optimized method. Otherwise, regex vs string is IMHO a matter of personal preference.
I'm going to guess you didn't generate that string yourself. So the question is, why parse it? This looks like the sort of question where you should take a step back and think of what you're trying to solve, and if another method might be cleaner.
I am not familiar with the ListViewSubItem class, but it seems like you have one of these and you have called ToString() on it. Now you are parsing the output of ToString() to see the model object your sub-item represents.
Does this not seem backwards to you? Maybe you should deal with the ListViewSubItem object itself (from a brief look at the documentation, what you want seems to be the Text property), rather than fiddling with what ToString() returns, which seems volatile and dependent on the implementation of that class's ToString() method (which, though likely not, could theoretically change from release to release). Not to mention corner cases like "what if the string contains the } character?"
For this in other reasons, as a general rule I think you should not have to deal with serialization when your data source is in memory the whole time.
So, in summary, if you have something like this:
ListViewSubItem item = /* ... */;
string s = item.ToString();
// TODO: parse {Debian} out of ListViewSubItem {Debian}
Why not this instead:
ListViewSubItem item = /* ... */;
string OS = item.Text;

Request.QueryString[] vs. Request.Query.Get() vs. HttpUtility.ParseQueryString()

I searched SO and found similar questions, but none compared all three. That surprised me, so if someone knows of one, please point me to it.
There are a number of different ways to parse the query string of a request... the "correct" way (IMO) should handle null/missing values, but also decode parameter values as appropriate. Which of the following would be the best way to do both?
Method 1
string suffix = Request.QueryString.Get("suffix") ?? "DefaultSuffix";
Method2
string suffix = Request.QueryString["suffix"] ?? "DefaultSuffix";
Method 3
NameValueCollection params = HttpUtility.ParseQueryString(Request.RawUrl);
string suffix = params.Get("suffix") ?? "DefaultSuffix";
Method 4
NameValueCollection params = HttpUtility.ParseQueryString(Request.RawUrl);
string suffix = params["suffix"] ?? "DefaultSuffix";
Questions:
Would Request.QueryString["suffix"] return a null if no suffix was specified?
(Embarrassingly basic question, I know)
Does HttpUtility.ParseQueryString() provide any extra functionality over accessing Request.QueryString directly?
The MSDN documentation lists this warning:
The ParseQueryString method uses query strings that might contain user input, which is a potential security threat. By default, ASP.NET Web pages validate that user input does not include script or HTML elements. For more information, see Script Exploits Overview.
But it's not clear to me if that means ParseQueryString() should be used to handle that, or is exposed to security flaws because of it... Which is it?
ParseQueryString() uses UTF8 encoding by default... do all browsers encode the query string in UTF8 by default?
ParseQueryString() will comma-separate values if more than one is specified... does Request.QueryString() do that as well, or what happens if it doesn't?
Which of those methods would correctly decode "%2b" to be a "+"?
Showing my Windows development roots again... and I would be a much faster developer if I didn't wonder about these things so much... : P
Methods #1 and #2 are the same thing, really. (I think the .Get() method is provided for language compatibility.)
ParseQueryString returns you something that is the functional equivalent of Request.Querystring. You would usually use it when you have a raw URL and no other way to parse the query string parameters from it. Request.Querystring does that for you, so in this case, it's not needed.
You can't leave off "suffix". You either have to pass a string or an index number. If you leave off the [] entirely, you get the whole NameValueCollection. If you mean what if "suffix" was not one of the QueryString values then yes; you would get null if you called Request.QueryString["suffix"].
No. The most likely time you would use it is if you had an external URL and wanted to parse the query string parameters from it.
ParseQueryString does not handle it... neither does pulling the values straight from Request.QueryString. For ASP.NET, you usually handle form values as the values of controls, and that is where ASP.NET usually 'handles' these things for you. In other words: DON'T TRUST USER INPUT Ever. No matter what framework is doing what ever for you.
I have no clue (I think no). However, I think what you are reading is telling you that ParseQueryString is returning UTF-8 encoded text - regardless if it was so encoded when it came in.
Again: ParseQueryString returns basically the same thing you get from Request.QueryString. In fact, I think ParseQueryString is used internally to provide Request.QueryString.
They would produce the equivalent; they will all properly decode the values submitted. If you have URL: http://site.com/page.aspx?id=%20Hello then call Request.QueryString["id"] the return value will be " Hello", because it automatically decodes.
Example 1:
string itsMeString = string.IsNullOrEmpty(Request.QueryString["itsMe"]) ? string.Empty : HttpUtillity.UrlDecode(Request.QueryString["itsMe"]);
Stright to your questions:
Not quite sure what do you mean by suffix, if you are asking what happens if the key is not present(you don't have it in the QueryString) - yes it will return null.
My GUESS here is that when constructed, Request.QueryString internally calls HttpUtillity.ParseQueryString() method and caches the NameValueCollection for subsequential access. I think the first is only left so you can use it over a string that is not present in the Request, for example if you are scrapping a web page and need to get some arguments from a string you've found in the code of that page. This way you won't need to construct an Uri object but will be able to get just the query string as a NameValueCollection if you are sure you only need this. This is a wild guess ;).)
This is implemented on a page level so if you are accessing the QueryString let's say in Page_Load event handler, you are having a valid and safe string (ASP.NET will throw an exception otherwise and will not let the code flow enter the Page_Load so you are protected from storing XSS in your database, the exception will be: "A potentially dangerous Request.QueryString value was detected from the client, same as if a post variable contains any traces of XSS but instead Request.Form the exception says Request.QueryString."). This is so if you let the "validateRequest" switched on (by default it is). The ASP.NET pipeline will throw an exception earlier, so you don't have the chance to save any XSS things to your store (Database). Switching it off implies you know what you're doing so you will then need to implement the security yourself (by checking what's comming in).
Probably it will be safe to say yes. Anyway, since you will in most cases generating the QueryString on your own (via JavaScript or server side code - be sure to use HttpUtillity.UrlEncode for backend code and escape for JavaScript). This way the browser will be forced to turn "It's me!" to "It%27s%20me%21". You can refer to this article for more on Url Encoding in JavaScript: http://www.javascripter.net/faq/escape.htm.
Please elaborate on that, couldn't quite get what do you mean by "will comma-separate values if more than one is specified.".
As far as I remember, none of them will. You will probably need to call HttpUtillity.UrlDecode / HttpUtillity.HtmlDecode (based on what input do you have) to get the string correctly, in the above example with "It's me!" you will do something like (see Example 1 as something's wrong with the code formatting if I put it after the numbered list).

how to get a String with String.Format to execute?

I have a little chunk of code (see below) that is returning the string:
string.Format("{0}----{1}",3,"test 2");
so how do I get this to actually "Execute"? To run and do the format/replacement of {0} and {1}?
My Code snippet:
StringBuilder sb = new StringBuilder();
sb.Append("{0}----{1}\",");
sb.AppendFormat(ReturnParamValue(siDTO, "siDTO.SuggestionItemID,siDTO.Title"));
string sbStr = "=string.Format(\""+sb.ToString()+");";
yes, ReturnParamValue gives the actually value of the DTO.
Anyways, I've taken a look at the following (but it doesn't say how to execute it:
How to get String.Format not to parse {0}
Maybe, I just should put my code snippet in a method. But, what then?
Why are you including String.Format in the string itself?
If you're looking for a generic "let me evaluate this arbitrary expression I've built up in a string" then there isn't a simple answer.
If, instead, you're looking at how to provide the parameters to the string from a function call, then you've got yourself all twisted up and working too hard.
Try something like this, based on your original code:
string result
= string.Format(
"{0}----{1}",
ReturnParamValue(siDTO, "siDTO.SuggestionItemID,siDTO.Title"));
Though, this won't entirely work since your original code seems to be only providing a single value, and you have two values in your format string - the {0} will be replaced with the value from your function, and {1} left unchanged.
What output are you expecting?
Does your ReturnParamValue() function try to return both the label and the value in a single string? If it does, and if they're comma separated, then you could try this:
var value = ReturnParamValue(siDTO, "siDTO.SuggestionItemID,siDTO.Title"));
var pieces = string.Split(',');
string result
= string.Format( "{0}----{1}", pieces[0], pieces[1]);
Though this is seriously working too hard if ReturnParamValue() is a method you control.
Update Fri 6 August
Check out the declaration for string.Format() as shown on MSDN:
public static string Format(
string format,
params Object[] args
)
Unlike the special casing you might have seen in C for printf(), there's nothing special or unusual about the way string.Format() handles multiple parameters. The key is the params keyword, which asks the compiler to provide a little "syntactic sugar" where it combines the parameters into an array for you.
Key here is that the wrapping doesn't happen if you're already passing a single object[] - so if you wanted to, you could do something like this:
object[] parameters
= ReturnParamValues(siDTO, "siDTO.SuggestionItemID,siDTO.Title");
string result
= string.Format("{0}----{1}----{2}", parameters);
Though, if I saw something like this in any codebase I maintained, I'd be treating it as a code-smell and looking for a better way to solve the problem.
Just because it's possible doesn't mean it's advisable. YMMV, of course.
I don't think you can execute it. Java is not really a interpreted language.
You may make use of scripting languages (which can even embed in your Java app as I know, start from JDK6) for such purpose, like Groovy
You could use RegEx to parse the three parameters out of the string, and then pass them to a real, actual string.Format method :-)
It looks like what you want is something like this:
string sbStr = string.Format("{0}----{1}", siDTO.SuggestionItemID, siDTO.Title);
Maybe i didn't understand your question completely, but it sounds like you need to format a format-string. If that's true you could maybe try something like this:
int width = 5;
string format = String.Format("{{0,{0}}}----{{1,{0}}}", width);
string result = String.Format(format, "ab", "cd");
So the trick is simply to escape the { or } by using a double {{ or }}.

Simple way to trim Dollar Sign if present in C#

I have a DataRow and I am getting one of the elements which is a Amount with a dollar sign. I am calling a toString on it. Is there another method I can call on it to remove the dollar sign if present.
So something like:
dr.ToString.Substring(1, dr.ToString.Length);
But more conditionally in case the dollar sign ever made an appearance again.
I am trying to do this with explicitly defining another string.
Convert.ToString(dr(columnName)).Replace("$", String.Empty)
--
If you are working with a data table, then you have to unbox the value (by default its Object) to a string, so you are already creating a string, and then another with the replacement. There is really no other way to get around it, but you will only see performance differences when dealing with tens of thousands of operations.
You could also use
string trimmed = (dr as string).Trim('$');
or
string trimmed = (dr as string).TrimStart('$');
If you are using C# 3.0 or greater you could use extension methods.
public static string RemoveNonNumeric(this string s)
{
return s.Replace("$", "");
}
Then your code could be changed to:
((String)dr[columnName]).RemoveNonNumeric();
This would allow you to change the implementation of RemoveNonNumeric later to remove things like commas or $ signs in foreign currency's, etc.
Also, if the object coming out of the database is indeed a string you should not call ToString() since the object is already a string. You can instead cast it.
Regex would work.
Regex.Replace(theString, "$", "");
But there are multiple ways to solve this problem.
dr[columeName].ToString().Replace("$", String.Empty)
Why don't you update the database query so that it doesn't return the dollar sign? This way you don't have to futz with it in your C# code.

Categories

Resources