Empty String to Double using (Try)Parse - c#

I've got a with 1.1 build system here using Parse for converting values (now it's 3.5).
string myString = String.Empty;
double myValue = double.Parse(myString);
throws a FormatException (I expected 0.0).
If I rewrite that using 2.0+
string myString = String.Empty;
double myValue;
if (double.TryParse(myString, out myValue))
//do something
I get the wanted 0.0, but unfortunately I lose the possibility to get a meaningful error message (in the else tree).
Why is giving me Parse an error and TryParse my expected value?
Is there any way to get the error message out of TryParse (time is not the problem)?
I don't want to work around it like that:
Avoid the error using if...then
myValue = myString.Length == 0 ? 0.0 : double.Parse(myString);
Two Calls if an error occured
if (!double.TryParse(myString, out myValue))
myValue = double.Parse(myString);

Parse throws an exception if the string cannot be be parsed and TryParse returns a bool. You can handle this bool (true if the parsing was successful, else false) to display the success/error message you want to show.
Since myValue is an out parameter it has to be set by the method so, if the string cannot be parsed, TryParse sets it as 0.0 which is why you're getting that number when using the TryParse method.

No, it is not possible to get the exact error message. You only want to know if it is possible to convert to double and the result, if it is possible. The exact reason why the conversion fails is hidden from you.

TryParse allows you to convert without throwing exception and returns true if successful. The action you take depends on you
if (!double.TryParse(myString, out myValue))
{
//throw exception here
}
It is useful when you are not sure if input will always be numbers

Why is giving me Parse an error and TryParse my expected value?
Because that's the way the interface is designed. TryParse does not throw an exception if the input has an invalid format. Instead it returns false.
Is there any way to get the error message out of TryParse (time is not the problem)?
No, but you can make your own error message.
if (double.TryParse(myString, out myValue))
{
//do something
}
else
{
throw new FooException("Problem!");
}
But if you want to throw an exception when there is an error it's simpler to just use Parse.

TryParse is implemented somehow like this:
try
{
Parse(...);
return true;
}
catch
{
return false;
}
So you can do it just the same way:
try
{
double.Parse(str, out dbl);
}
catch (Exception ex)
{
// Do something with ex.Message
dbl = 0.0;
}
// Continue with dbl.

Forget double.TryParse, as it won't tell you (by design) why the parsing failed. Do it The Old Way:
string myString = String.Empty;
double myValue = 0.0;
try
{
myValue = double.Parse(myString);
}
catch (FormatException)
{
// Now you have a meaningful story here!
}

Out parameters has to be set, therefore if TryParse fails it will initialize the output to it's default before it returns, however you will and in the "else" loop... Meaning it failed...
Try running the code below, that will show you that TryParse actually overwrites the value, yet indicates that the parse fails...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ParseAndOutput("");
ParseAndOutput("1.0");
ParseAndOutput("ABC");
}
private static void ParseAndOutput(string input)
{
double value = -1;
if (double.TryParse(input, out value))
{
Console.WriteLine("Parse succeeded for '"+input+"', try parse changed to: " + value);
}
else
{
Console.WriteLine("Parse failed for '" + input + "', try parse changed to: " + value);
}
}
}
}
So both Parse and TryParse fails on string.Empty, they just report that failure differently which is the whole point of TryParse, it is never meant to throw an exception...

Related

Ignore dots in Convert.ToDecimal and return 0

I am using Convert.ToDecimal in linq, sometime amount value contains dot (.) as user want to write .50 or similar, as soon as they enter dot (using Numeric keypad from mobile), code is getting executed and throwing an exception.
I am getting string is not correct format exception for below code
var enteredAmountInTenders = TenderListCollection.Sum(x => Convert.ToDecimal(string.IsNullOrEmpty(x.Amount) ? "0" : x.Amount));
How can I ignore dot for above code and just get 0?
I would use decimal.TryParse instead of Convert.ToDecimal to cast the value.
var enteredAmountInTenders = TenderListCollection
.Sum(x => !decimal.TryParse(x.Amount,out var result) ? 0 : result);
you could check this before your set your property for the object in your TenderListCollection.
private string _amount = "0";
public string Amount
{
get
{
return _amount;
}
set
{
if(!string.IsNullOrEmpty(value))
{
if(value != ".")
{
_amount = value;
}
}
}
}
In general i dont like storing amounts as string, so i also would suggest to rename the Amount to GivenAmount and have an Amount Property which is a decimal, this way our code is clean and you dont need to parse in a Lambda expression.

C# Ignore error/warning on Substring

I use Substring to decode a generated code for activating
but when a user enter wrong code like 1 or 123
c# stop and say "Index and length must refer to a location within the string." or ..
how to ignore it without check length ...
in php we can ignore warnings and error by using "#"
#myfunc(12);
but how in C# ?
The short answer is, you can't.
The correct answer is you shouldn't, and to check that the input is valid.
The horrible answer would look something like this:
public void SwallowExceptions(Action action)
{
try
{
action();
}
catch
{
}
}
public string DoSomething()
{
string data = "TerribleIdea";
string result = null;
SwallowExceptions(() => result = data.Substring(0, 10000));
return result;
}

Parse any string number to number

I'm trying to found out if a string value is any kind of number. The numbers can be anything like $23.23, (232.3434), 34.4545, 64.345, 34.34%
For dollars and percentages I can remove the % and $ symbols from the string, but I can't get this number to get parsed using this code.
string _number = "64.345";
double _double;
if (Double.TryParse(_number, NumberStyles.Any, null, out _double))
{
}
else
{
}
What am I doing wrong in this code?
What is your culture settings for your OS, it likely is misinterpreting the ..
If you passed in CultureInfo.InvariantCulture instead of null for the format provider that should solve your problem. When you pass in null it uses CultureInfo.CurrentCulture and your PC is set to a culture that does not interpret a . as a separator for decimal numbers.
You could try and use the double.Parse() instead with a try catch statement, like this:
string _number = "64.345";
double _double;
try
{
_double = Double.Parse(_number)
// Other actions
}
catch (FormatException ex)
{
// Actions for when invalid parameter is given for parse
}

C# If Contains?

I am new to C# and I'm trying to write a contains statement. I want the process to read the test variable and if it contains the word error then print the variable if it does not contain an error then print no error. I think my process is close except when I run the code below I get an error when the CLI runs.
"object reference not set to an instance of an object"
Any help would be appreciated!
while (true)
{
test = queue.GetMessage();
if (test.AsString.Contains("error"))
{
Console.WriteLine(string.Format("Variable: {0}", test.AsString));
}
else
Console.WriteLine(string.Format("No Error: {0}", test.AsString));
}
var message = queue.GetMessage()?? string.Empty;
var formattedMessage =
String.Format(
(message.IndexOf("error", StringComparison.OrdinalIgnoreCase) >= 0)
? "No Error: {0}"
: "Variable: {0}", message);
Console.WriteLine(formattedMessage);
Useful references:
Unique ways to use the Null Coalescing operator
Simplify conditional string format
If queue.GetMessage() return a string, then you don't need AsString. If you want to convert it to a string, override ToString().
while (true) {
test = queue.GetMessage();
if (test.ToString().Contains("error")) {
...
} else {
...
}
}
You can always guarantee that ToString() will be present because it's defined in the object base class. Just be sure it returns something intelligible, because default implementations may not.

ASP.net Converting inputbox string to integer?

I have been trying for ages to convert a string taken from an input box in my asp form and converting it to an integer.
This integer variable will then be used for a database operation I have planned.
Here is what I have tryed:
string mytxtCHI = txtID.Text;
int #CHI = Convert.ToInt16(mytxtCHI);
Error:
System.FormatException
{"Input string was not in a correct format."}
Things I have tried:
- string mytxtCHI = txtID.Text;
int myNewID=(Int32.Parse(txtID.Text));
Thankyou for your time :)
Your way is correct, but what you should do to avoid errors
int myNewID = 0;
if(int.TryParse(txtID.Text, out myNewID))
{
//your code here
}
else
{
//your error handling here
}
You should use tryparse:
string mytxtCHI = txtID.Text;
int number;
bool result = Int32.TryParse(mytxtCHI , out number);
if (result)
{
Console.WriteLine("Converted '{0}' to {1}.", mytxtCHI , number);
}
else
{
if (value == null) value = "";
Console.WriteLine("Attempted conversion of '{0}' failed.", mytxtCHI );
}
Put a breakpoint on the line in Visual Studio. In debug mode, run to the breakpoint, and hover over txtID.Text to see what's in it.
When in the page lifecycle are you checking this value? Check it after Page Init. Check HttpRequest.Form to see what came down the wire.
You should use Int.TryParse, and handle the case when the value isn't a valid integer.
string mytxtCHI = txtId.Text;
int val;
if (!int.TryParse(mytxtCHI, out val))
{
// error here, value was not a valid integer.
}
// here, val contains the value, expressed as an integer.
Use watch window or System.Diagnostics.Debug.WriteLine(mytxtCHI) to check what's the value you are passing, is it blank?

Categories