Using double.Parse with a null value - c#

Below is my statement:
double? My_Value = null;
if (Request.Form["MyValue"] != null)
My_Value = double.Parse(Request.Form["MyValue"].ToString());
When I try to submit my form with no value for 'MyValue' I get a run time error saying 'Input string was not in a correct format.'. When I try to use:
My_Value = double.TryParse(Request.Form["MyValue"].ToString());
Visual Studio gives me a compile error that says 'No overload for method 'TryParse' takes 1 arguments'.
When I provide a value for 'My_Value', the form submits. How do I get the program to accept a null value? Thank you.

You need to declare a double variable to store the result and pass it to TryParse as an out argument, so it will be assigned if the parse succeeded:
double result;
var isValid = double.TryParse(Request.Form["MyValue"].ToString(), out result);
Also TryParse is different than Parse method, it doesn't return a numerical result, it returns a boolean result that indicates whether the parsing is succeeded or not.So you need to assign that result and check it's value to make sure parsing was successful.Or you could directly check the result without storing it in a variable.
double result;
double? My_Value = double.TryParse(Request.Form["MyValue"].ToString(), out result)
? (double?)result
: null;

Both solutions will result in 0;
string myString = null;
double result = Convert.ToDouble(myString);
OR
string myString = null;
double result = double.Parse(myString ?? "0");

The problem with your first case isn't just about handling nulls but rather about handling anything that cannot be parsed (since you are accepting a value from an untrustworthy source). Using TryParse is the way to go here.
However, the TryParse method accepts two arguments, the first the value to parse, the second a value to assign to if parsing succeeds (as an out) parameter.
For just such an occasion whereby you'd like a nullable result, a custom utility method can come in handy:
public static class NullableDouble
{
public static double? TryParse(string input)
{
double result;
var success = double.TryParse(input, out result);
return success ? result as double? : null;
}
}
Useable like so:
var myValue = NullableDouble.TryParse((Request.Form["MyValue"] ?? string.Empty).ToString());

The signature for TryParse is bool TryParse(string str, out double result)
Use it like this:
double result;
var success = double.TryParse(Request.Form["MyValue"].ToString(), out result);
My_Value = success? result : 0d;
As "usr" mentioned in the comments, the next time you get an error like this, you should check the MSDN documentation first before coming here.

Related

Convert string to INT in C# (When String is 'E0305' To convert INT is not Work

I want to convert string to int but some time is not working.
Here is my code:
public static int ToInt(String pStr)
{
return Convert.ToInt32(Microsoft.VisualBasic.Conversion.Val(pStr));
}
Int i = ToInt("F0005");
Output is 0 - it works fine.
But when I pass in a value like this
Int i = ToInt("E0305");
Then I get an error "Out-of-range exception".
I have a mix of values, some are int and some are strings; I want to pass each and every value in loop and convert it to int, but when I pass this value then I get an error.
If you just want to skip invalid string value, it is better to use TryParse instead of returning 0 (which might be valid value). At your calling code it should look like this:
string val = "F0005";
if (int.TryParse(val, out int i) {
// parse success. you can use i here
}
else {
// parse failed.
}
If you really want it to be 0, this should work
string val = "F0005";
int i = int.TryParse(val, out int x) ? x : 0;
You can do it in C# alone without VB.NET library
public static int ToInt(string pStr)
{
return int.Parse(pstr);
}
Noted that this will throw exception if pStr is not a valid integer string. In your case, it might also throw exception if the value is too big, which you might need long instead to hold bigger numbers.
public static long ToInt64(string pStr)
{
return long.Parse(pstr);
}
Also, I just noticed that you are trying to parse "E0305" which is not really a valid format (as far as I know). The closest one is "1E305", which means 1 with 305 zeroes afterward. If you need to parse an integer that big, you might need BigInteger
public static BigInteger ToBigInteger(string pStr)
{
return BigInteger.Parse(pstr, System.Globalization.NumberStyles.AllowExponent);
}
The System.Globalization.NumberStyles.AllowExponent part is there to allow parsing the number in exponent representation.
Try using int.TryParse() method for those cases where you have some unexpected and you do not want exceptions in proces of parsing them.
Use case for it would be:
var isValid = int.TryParse(pStr, out int result);
Also another benefit of using it is that you have return value that provides you a way to handle unsuccessful parsing call.

casting ExecuteScalar() result c#

why would this work
int collectionCharge = (int)cmdCheck.ExecuteScalar();
but this produces an exception
double collectionCharge = (double)cmdCheck.ExecuteScalar();
System.InvalidCastException: Specified cast is not valid.
why would it not be valid?
EDIT
I am trying to simply return a single result from a query, that gets the price of some freight. So I can't turn this into an int because it must have decimals, hence trying to cast to a double. I am still learning asp.net so if there's a better way to achieve this, please do point me in the right direction :)
EDIT 2
the full code with SQL...
using (SqlCommand cmdCheck = new SqlCommand("SELECT FREIGHT_PRICE FROM FREIGHT_QUOTER_BELNL_NEW WHERE CUSTOMER_NO = #CUSTOMER_NO AND COUNTRY = #COUNTRY AND ROUND(WEIGHT_FROM,0) < #WEIGHT AND ROUND(WEIGHT_TO,0) >= #WEIGHT AND SHIPVIA = '48';", connection))
{
double collectionCharge = (double)cmdCheck.ExecuteScalar();
FreightAmount = collectionCharge;
}
The problem here is that ExecuteScalar is returning an int which is boxed into an object. In order to convert to a double you must first unbox to an int then convert to a double
double collectionCharge = (double)(int)cmdCheck.ExecuteScalar();
Use the Convert.ToXXX to avoid invalid cast exceptions.
I.E
collectionCharge=Convert.ToDouble(cmdCheck.ExecuteScalar());
As it appears that ExecuteScalar returns an Object so the code:
double collectionCharge = (double)cmdCheck.ExecuteScalar();
Could still fail
With thanks to #DJKRAZE.
I updated my query to SELECT CASE(FREIGHT_PRICE AS FLOAT) which now works with the (double) cast.
double collectionCharge = (double)cmdCheck.ExecuteScalar();
After reading all answers, I had a case of receiving the Decimal values indeed, and the solution was easy!
I just declared the function as string and received the Decimal value as string!
public static string Sals_AccountExpensesGetSums(int accountID)
{
SqlParameterHelper sph = new
SqlParameterHelper(ConnectionString.GetWriteConnectionString(),
"sals_AccountExpenses_GetAllSums", 1);
sph.DefineSqlParameter("#AccountID", SqlDbType.Int, ParameterDirection.Input, accountID);
string res = sph.ExecuteScalar().ToString();
return res;
}
and in the business layer i changed the result to double!
public static decimal GetAccountExpensesSums(int accountId)
{
string res = "";
decimal sums = 0;
res = DBAccount.Sals_AccountExpensesGetSums(accountId);
// check so we will not have exception
if ( res != "")
sums = Convert.ToDecimal(res);
return sums;
}
and the result was perfect as needed: 889678.70
I would recommend using this code:
object o = c.ExecuteScalar();
if (o != null)
{
int x = Int32.Parse(o.ToString());
}
This does two things. First it makes sure that your c.ExecuteScalar() isn't returning null If it did so and you tried to cast, you'd have problems.
Second, it makes casting much simpler because it can be applied to pretty much all cases when reading from a query.
The object becomes a string. If you want it as a string, you're done.
If you want it as a boolean, check to see if that string.Equals("true")
If you want it as an int, Int32.Parse(string);
if you want it as a long, Int64.Parse(string);
Basically, you won't have to worry about fully understanding overloading/explicit conversion.

Novice enquiry on using TryParse() properly

I've just tried TryParse, and am new to C# and just trying to understand everything, and then hopefully best practices...
Syntactically this works:
double number = Double.Parse(C.ReadLine());
Does TryParse only return a boolean, true if parse succeeds?
When I do this:
double number;
bool b = Double.TryParse(C.ReadLine(), out number);
number is the parsed input, from C.ReadLine(), as expected, everything works. Is this how TryParse is normally used? Trying to be efficient, appreciate advice like this.
Any advice on approach welcome, plus info on online resources for Try(things).
You use TryParse when it may fail, and you don't want your code to throw an exception.
For example
if (!Double.TryParse(someinput, out number))
{
Console.WriteLine("Please input a valid number");
}
Parse will return the double value if it succeeds and throws an exception otherwise. TryParse will return a boolean value representing the success of the operation and if it does succeed, it fills in the parsed value in the out argument you pass to it. It will never throw an exception.
In general, you should use TryParse when you expect the input string to not be a valid number and you have the logic to handle it (and display an error message, for instance).
If you don't expect the input string to be anything except a valid double you should use Parse.
The only differnce is that TryParse won't thow an exception if it can't parse the double.
This is handy when you want to assign a default value or ignore the value in your code
Example:
double number;
if (Double.TryParse(C.ReadLine(), out number))
{
// this is a double so all good
}
else
{
// not a valid double.
}
Example:
double number;
progressBar.Value = Double.TryParse(C.ReadLine(), out number) ? number : 4.0;
// If number is a valid double, set progressbar, esle set default value of 4.0
You also asked aboy TyrParse on Enum, this can be done like this
DayOfWeek fav;
if (Enum.TryParse<DayOfWeek>(Console.ReadLine(), out fav))
{
// parsed
}

How to call a function based on string value in C#

I want to convert a string to specific type based on the value of other string
Suppose I have two strings str1, str2.
If str2 is double then I want to call convert.ToDouble(str1) and return the Double value. Is there any way to accomplish this?
I tried using reflections (using methodInfo object to invoke)
But still it returns again an object for which I need to convert.
Please help..
Use the double.TryParse Method.
The method attempts to convert a string to a double and if it fails it returns false.
If I'm understanding you correctly, this is what you want:
private static double ConditionalConvertToDouble(string str1, string str2) {
double converted;
if (double.TryParse(str2, out converted)) {
// str2 can be converted to a double, so return str1 converted to a double.
return Convert.ToDouble(str1);
} else {
// I'm throwing an exception here if str1 cannot be converted to a double; you
// might want to do something different.
throw new ArgumentException("str1 cannot be converted to a double");
}
}
Call the method like this:
var d = ConditionalConvertToDouble("11", "22");
double result;
Double.TryParse(str1, out result);
if str1 is double, result will have its value, otherwise result will have 0. It will not throw any exception.
Hope it helps.
The following method will attempt to get the double value from "str1" if and only if "str2" also represents a double. If either of the numbers are not doubles, it will return double.NaN.
This method avoids throwing exceptions, but still allows you to check if you have a valid number.
public double GetFirstDoubleIfSecond(string str1, string str2)
{
double myDouble;
if(double.TryParse(str2, out myVal) && double.TryParse(str1, out myVal))
{
return myDouble
}
return double.NaN;
}
If you are expecting NaN values in your string, then you can use the following method, which will throw an exception if either of the strings are not doubles. Otherwise, it will return the string value represented in "str1".
public double GetFirstDoubleIfSecondWithExceptions(string str1, string str2)
{
double.Parse(str2);
return double.Parse(str1);
}
I think that switch-case operator should help to you. You should to specify some cases depending on one of your input string and make right decision. Your method should return object, if you really don't know which type exactly will return your method.
public object MyMethod(string str1, string str2)
{
switch(something)
{
case 1:
case 2:
return double.Parse(str1);
break;
case 3:
case 4:
return int.Parse(str1);
break;
default
return null;
}
}
where something is the criterion you should to specify.
After that System.Object.GetType() method can help you to detirmine which type was returned by your method.

Better way to cast object to int

This is probably trivial, but I can't think of a better way to do it. I have a COM object that returns a variant which becomes an object in C#. The only way I can get this into an int is
int test = int.Parse(string.Format("{0}", myobject))
Is there a cleaner way to do this? Thanks
You have several options:
(int) — Cast operator. Works if the object already is an integer at some level in the inheritance hierarchy or if there is an implicit conversion defined.
int.Parse()/int.TryParse() — For converting from a string of unknown format.
int.ParseExact()/int.TryParseExact() — For converting from a string in a specific format
Convert.ToInt32() — For converting an object of unknown type. It will use an explicit and implicit conversion or IConvertible implementation if any are defined.
as int? — Note the "?". The as operator is only for reference types, and so I used "?" to signify a Nullable<int>. The "as" operator works like Convert.To____(), but think TryParse() rather than Parse(): it returns null rather than throwing an exception if the conversion fails.
Of these, I would prefer (int) if the object really is just a boxed integer. Otherwise use Convert.ToInt32() in this case.
Note that this is a very general answer: I want to throw some attention to Darren Clark's response because I think it does a good job addressing the specifics here, but came in late and wasn't voted as well yet. He gets my vote for "accepted answer", anyway, for also recommending (int), for pointing out that if it fails (int)(short) might work instead, and for recommending you check your debugger to find out the actual runtime type.
The cast (int) myobject should just work.
If that gives you an invalid cast exception then it is probably because the variant type isn't VT_I4. My bet is that a variant with VT_I4 is converted into a boxed int, VT_I2 into a boxed short, etc.
When doing a cast on a boxed value type it is only valid to cast it to the type boxed.
Foe example, if the returned variant is actually a VT_I2 then (int) (short) myObject should work.
Easiest way to find out is to inspect the returned object and take a look at its type in the debugger. Also make sure that in the interop assembly you have the return value marked with MarshalAs(UnmanagedType.Struct)
Convert.ToInt32(myobject);
This will handle the case where myobject is null and return 0, instead of throwing an exception.
Use Int32.TryParse as follows.
int test;
bool result = Int32.TryParse(value, out test);
if (result)
{
Console.WriteLine("Sucess");
}
else
{
if (value == null) value = "";
Console.WriteLine("Failure");
}
Maybe Convert.ToInt32.
Watch out for exception, in both cases.
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;
I am listing the difference in each of the casting ways. What a particular type of casting handles and it doesn't?
// object to int
// does not handle null
// does not handle NAN ("102art54")
// convert value to integar
int intObj = (int)obj;
// handles only null or number
int? nullableIntObj = (int?)obj; // null
Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null
// best way for casting from object to nullable int
// handles null
// handles other datatypes gives null("sadfsdf") // result null
int? nullableIntObj2 = obj as int?;
// string to int
// does not handle null( throws exception)
// does not string NAN ("102art54") (throws exception)
// converts string to int ("26236")
// accepts string value
int iVal3 = int.Parse("10120"); // throws exception value cannot be null;
// handles null converts null to 0
// does not handle NAN ("102art54") (throws exception)
// converts obj to int ("26236")
int val4 = Convert.ToInt32("10120");
// handle null converts null to 0
// handle NAN ("101art54") converts null to 0
// convert string to int ("26236")
int number;
bool result = int.TryParse(value, out number);
if (result)
{
// converted value
}
else
{
// number o/p = 0
}
There's also TryParse.
From MSDN:
private static void TryToParse(string value)
{
int number;
bool result = Int32.TryParse(value, out number);
if (result)
{
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}
else
{
if (value == null) value = "";
Console.WriteLine("Attempted conversion of '{0}' failed.", value);
}
}
Strange, but the accepted answer seems wrong about the cast and the Convert in the mean that from my tests and reading the documentation too it should not take into account implicit or explicit operators.
So, if I have a variable of type object and the "boxed" class has some implicit operators defined they won't work.
Instead another simple way, but really performance costing is to cast before in dynamic.
(int)(dynamic)myObject.
You can try it in the Interactive window of VS.
public class Test
{
public static implicit operator int(Test v)
{
return 12;
}
}
(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass
You can first cast object to string and then cast the string to int;
for example:
string str_myobject = myobject.ToString();
int int_myobject = int.Parse(str_myobject);
this worked for me.
int i = myObject.myField.CastTo<int>();
This worked for me, returning 0 also when myobject contains a DBNull
int i = myobject.ToString().Cast<int>().FirstOrDefault();

Categories

Resources