Im playing around with TryParse()
But lets say the parsing fails, then returns false, and ... nothing..
Is there a way to get info back about what failed the parsing?
I saw something like that at codeproject, but i didnt really understand it.
Thanks :)
No, there's no way of getting that information from the normal .NET routines. You could check for a few things manually:
Try parsing the number as a decimal. If that works, but parsing as an integer doesn't, then it's either out of the range of the integer, or it's not an integer.
Look for non-decimal, non +/-, non-decimal-point characters
Check whether it's an empty string
You haven't said what you're trying to parse (integer, double etc) or what options you want (allow hex, thousands separators etc) which makes it harder to give a good list of things to check.
The TryParse() method is there when you want to be shielded from any exceptions.
If you want to see the exceptions then why not use the standard Parse() method in a try/catch block which will allow you to view any FormatExceptions etc thrown?
As expected, with exception handling, this could impact performance however if the Parse() is expected to succeed then this should be tolerable.
Why not just use the regular Parse method instead?
Related
I encountered a scenario where i have to send an array of integers as parameter from specflow feature file. I could have used tables which i don't want to do as i have send as row[] or col[]. If i pass parameter as a string
eg: Given set the value as '470,471,472,472'
and receive it and do split in step definition file. How different is StepArgumentTransformation from the above scenario? Is any other benefit in using step argument transformation. I understand we can convert XML,Date or any object. Why do we have to use stepargumenttransformation???
I hope I understood the question correctly.
Specflow supports some automatic transformation out of the box, so things like converting to Date, Double, int etc etc, and it does these by default as there is no ambiguity about them. You can easily convert a string to a double or a Date as you know the locale being used.
Why isn't converting to arrays supported? I suppose it could be, but there is some ambiguity. What should the list separator be? a comma? What about locales that use that as a separator between the whole and fractional part of a number?
So providing a default implementation of something which converted a list to int[] or IEnumerable<int> could be possible, but its just likely to get some people asking why it doesn't work for them when they have used ☃ as a list separator.
It's better to leave the things with ambiguity to individuals to implement, rather than guess at the best implementation.
The StepArgumentTransformation you want is very simple to write and could be included in an external step assembly if you wanted to share it amongst many projects.
So to answer your many questions:
It's not really any different, it just encapsulates it in a single place, which is good practise, which is a benefit.
Yes you can convert any object.
You don't have to use StepArgumentTransformation, many people don't, but IMHO they make your life much easier
Is there any side effect of passing and extra argument to string.Format function in C#? I was looking at the string.Format function documentation at MSDN ( http://msdn.microsoft.com/en-us/library/b1csw23d.aspx) but unable to find an answer.
Eg:-
string str = string.Format("Hello_{0}", 255, 555);
Now, as you can see that according to format string, we are suppose to pass only one argument after it but I have passed two.
EDIT:
I have tried it on my end and everything looks fine to me. Since I am new to C# and from C background, I just want to make sure that it will not cause any problem in later run.
Looking in Reflector, it will allocate a little more memory for building the string, but there's no massive repercussion for passing in an extra object.
There's also the "side effect" that, if you accidentally included a {n} in your format string where n was too large, and then added some spare arguments, you'd no longer get an exception but get a string with unexpected items in.
If you look at the exception section of the link you provide for string.Format
"The index of a format item is less than zero, or greater than or equal to the length of the args array."
Microsoft doesn't indicate that it can throw if you have too much arguments, so it won't. The effect is a small loss of memory due to an useless parameter
I just need to know if the value is numeric. I don't need to do anything with the value. Is this the best way? Feel dirty creating a variable that I won't ever use beyond this:
int val;
if(int.TryParse(txtFoo.Text, out val))
{
....
}
Yes, using the relevant TryParse method and ignoring the out parameter is the best way of doing this.
You may want to wrap this up into your own set of helper methods (which could specify the appropriate culture etc, if the default isn't right for you) and just return a bool without the out parameter to make them easier to call.
Of course, you need to work out what kind of parsing is most appropriate - even for integers, you need to consider whether the range of Int32 is enough for your use case. In my experience, most numeric input has its own "natural" range of valid values, which is unlikely to be exactly the range of any predefined type. You may therefore want to expand your helper methods to include the range of valid values to accept.
"is numeric" is an ambiguous term.
Culture-aware?
Allow thousands and/or decimal separators?
Allow scientific notation?
Allow a sign (before? after?...)
What range of values do you allow? Signed 32-bit integer (Int32.TryParse), Unsigned 32-bit integer (UInt32.TryParse), decimal, double, ...
Hence there is no "best" way, and the Framework provides a multitude of different ways to parse numbers.
You can use Regular expressions
Regex _isNumber = new Regex(#"^\d+$");
_isNumber.IsMatch(txtFoo.Text);
This will only match Ints, but you can write one that also matches decimals.
It's not as flexible as int.TryParse, but you could check to see if each character is a number:
bool isInt = txtFoo.Text.All(c => char.IsNumber(c));
In general, though, I would recommend sticking with int.TryParse. You can even call the unused parameter "ignored" to be explicit about your intent, e.g.:
int ignored;
bool isInt = int.TryParse(txtFoo.Text, out ignored);
That is the recommended way of doing it in C#. However, you could also add Microsoft.VisualBasic.dll as a reference to your project and then use Microsoft.VisualBasic.Information.IsNumeric()
You can try using Regex parsing to determine that there are no non-numeric characters in a string, or you can use Int.TryParse(), Double.TryParse(), Float.TryParse() depending on the input.
bool test (string teststring)
{ for (i=0;i==teststring.length;i++){
if instr("0123456789.,-+Ee",teststring.substring(i,1) <0){return false;}
// some additional tests below here if you like
return true;
}
however E1001E12e.12e would be noted as a number a little bit more magic is needed to do a clean check, but then you might be able to determine if its a int or a float too..
That's the best way of doing it in my knowledge - that's what our company standards adhere to anyway due to the error handling being done within the parsing.
This details the advantages: https://web.archive.org/web/20150510214425/http://www.dotnetperls.com:80/int-tryparse
Today I read an article where it's written that we should always use TryParse(string, out MMM) for conversion rather than Convert.ToMMM().
I agree with article but after that I got stuck in one scenario.
When there will always be some valid value for the string and hence we can also use Convert.ToMMM() because we don't get any exception from Convert.ToMMM().
What I would like to know here is: Is there any performance impact when we use TryParse because when I know that the out parameter is always going to be valid then we can use Convert.ToMMM() rather TryParse(string, out MMM).
What do you think?
If you know the value can be converted, just use Parse(). If you 'know' that it can be converted, and it can't, then an exception being thrown is a good thing.
EDIT: Note, this is in comparison to using TryParse or Convert without error checking. If you use either of the other methods with proper error checking then the point is moot. I'm just worried about your assumption that you know the value can be converted. If you want to skip the error checking, use Parse and die immediately on failure rather than possibly continuing and corrupting data.
When the input to TryParse/Convert.ToXXX comes from user input, I'd always use TryParse. In case of database values, I'd check why you get strings from the database (maybe bad design?). If string values can be entered in the database columns, I'd also use TryParse as you can never be sure that nobody modifies data manually.
EDIT
Reading Matthew's reply: If you are unsure and would wrap the conversion in a try-catch-block anyway, you might consider using TryParse as it is said to be way faster than doing a try-catch in that case.
There is significant difference regarding the developing approach you use.
Convert: Converting one "primitive" data in to another type and corresponding format using multiple options
Case and point - converting an integer number in to its bit by bit representation. Or hexadecimal number (as string) in to integer, etc...
Error Messages : Conversion Specific Error Message - for problems in multiple cases and at multiple stages of the conversion process.
TryParse: Error-less transfer from one data format to another. Enabling T/F control of possible or not.
Error Messages: NONE
NB: Even after passing the data in to a variable - the data passed is the default of the type we try to parse in to.
Parse: in essence taking some data in one format and transfer it in to another. No representations and nothing fancy.
Error Messages: Format-oriented
P.S. Correct me if I missed something or did not explain it well enough.
For the project that I'm currently on, I have to deliver specially formatted strings to a 3rd party service for processing. And so I'm building up the strings like so:
string someString = string.Format("{0}{1}{2}: Some message. Some percentage: {3}%", token1, token2, token3, number);
Rather then hardcode the string, I was thinking of moving it into the project resources:
string someString = string.Format(Properties.Resources.SomeString, token1, token2, token3, number);
The second option is in my opinion, not as readable as the first one i.e. the person reading the code would have to pull up the string resources to work out what the final result should look like.
How do I get around this? Is the hardcoded format string a necessary evil in this case?
I do think this is a necessary evil, one I've used frequently. Something smelly that I do, is:
// "{0}{1}{2}: Some message. Some percentage: {3}%"
string someString = string.Format(Properties.Resources.SomeString
,token1, token2, token3, number);
..at least until the code is stable enough that I might be embarrassed having that seen by others.
There are several reasons that you would want to do this, but the only great reason is if you are going to localize your application into another language.
If you are using resource strings there are a couple of things to keep in mind.
Include format strings whenever possible in the set of resource strings you want localized. This will allow the translator to reorder the position of the formatted items to make them fit better in the context of the translated text.
Avoid having strings in your format tokens that are in your language. It is better to use
these for numbers. For instance, the message:
"The value you specified must be between {0} and {1}"
is great if {0} and {1} are numbers like 5 and 10. If you are formatting in strings like "five" and "ten" this is going to make localization difficult.
You can get arround the readability problem you are talking about by simply naming your resources well.
string someString = string.Format(Properties.Resources.IntegerRangeError, minValue, maxValue );
Evaluate if you are generating user visible strings at the right abstraction level in your code. In general I tend to group all the user visible strings in the code closest to the user interface as possible. If some low level file I/O code needs to provide errors, it should be doing this with exceptions which you handle in you application and consistent error messages for. This will also consolidate all of your strings that require localization instead of having them peppered throughout your code.
One thing you can do to help add hard coded strings or even speed up adding strings to a resource file is to use CodeRush Xpress which you can download for free here: http://www.devexpress.com/Products/Visual_Studio_Add-in/CodeRushX/
Once you write your string you can access the CodeRush menu and extract to a resource file in a single step. Very nice.
Resharper has similar functionality.
I don't see why including the format string in the program is a bad thing. Unlike traditional undocumented magic numbers, it is quite obvious what it does at first glance. Of course, if you are using the format string in multiple places it should definitely be stored in an appropriate read-only variable to avoid redundancy.
I agree that keeping it in the resources is unnecessary indirection here. A possible exception would be if your program needs to be localized, and you are localizing through resource files.
yes you can
new lets see how
String.Format(Resource_en.PhoneNumberForEmployeeAlreadyExist,letterForm.EmployeeName[i])
this will gave me dynamic message every time
by the way I'm useing ResXManager