Casting keeps on getting errors - c#

I have a CSV with the following data (no header)
12,2010,76.5
2,2000,45
12,1940,30.2
and I'm reading the data into a List<List<object>>.
To know what's in each line and column / row I'm using the following loop
List<List<object>> data = CSVReaderNoHeader.Read("input")
for (var i = 0; i < data.Count; i++)
{
double month = (double)(int)data[i][0];
print($"month:{month} ////END");
double year= (double)(int)data[i][1];
print($"year:{year} ////END");
double temperature= (double)data[i][2];
print($"temperature:{temperature} ////END");
}
Yes I need to create doubles, that's why I'm unboxing and casting (could have use double.Parse instead).
I'm able to print the month and the year just fine, but when reaching double temperature= (double)data[i][2];, throws the following error
InvalidCastException: Specified cast is not valid.
I printed what's in data[i][2] before that line (print(data[i][2]);) just to see if everything was in order there and got 76.5 as expected. Then, tested also using
double temperature= (double)(double)data[i][2];
double temperature= (double)(float)data[i][2];
(which i think it would be unnecessary to add that extra (double) / (float)) and
object tempr = data[i][2];
double temperature;
temperature = (double)tempr;
but the problem remained. So, I went on and ran print(data[i][2].GetType()); to see if the type returned there could be cast into a double. I got as result System.String.
Knowing this, then I tried then the methods double.TryParse, double.Parse and Convert.ToDouble but none worked
double.TryParse(data[i][2], out temperature);
Argument 1: cannot convert from 'object' to string.
double temperature = double.TryParse(data[i][2]);
Argument 1: cannot convert from 'object' to string.
double temperature = System.Convert.ToDouble(data[i][2]);
FormatException: Input string was not in a correct format.
How then I have to cast it?

Because your numbers use a point as decimal separator and your system localization can use a different, you can use that:
using System.Xml;
double temperature = XmlConvert.ToDouble(data[i][2].ToString());
It will raise an exception in case of parsing error.
So you can try...catch to manage it.
Perhaps you will need to add System.Xml to assembly references of the project.
Else you can use #Fabjan solution:
if (double.TryParse(data[i][2].ToString(),
System.Globalization.NumberStyles.Any,
System.Globalization.CultureInfo.InvariantCulture,
out var temperature);
IsOk();
else
IsNotOk();

Related

Why can't I concatenate int data in C#? [duplicate]

This question already has answers here:
Cannot implicitly convert type 'double' to 'int'. -error
(4 answers)
Closed 9 months ago.
I am a beginner in C#. I'm currently trying to concatenate int data and using the Math square root function, but after running the program, it produces an error.
The code are as follows.
using System;
namespace NewProject
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Type any number");
int number = Convert.ToInt32(Console.ReadLine());
int square_root = Math.Sqrt(number);
Console.WriteLine("$The square root of {square_root} is " , square_root);
}
}
}
C:\Users\ajmal\Documents\Learn C#\New Project\Program.cs(13,31): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?) [C:\Users\ajmal\Documents\Learn C#\New Project\N
ew Project.csproj]
The build failed. Fix the build errors and run again.
Any tips and help would be appreciated
The compiler message tells:
Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
It even gives you the location of the error:
New Project\Program.cs(13,31)
Line 13, position 31
If you look there, not very far you should find this line:
int square_root = Math.Sqrt(number);
If you look that the Math.Sqrt documentation, you'll see that Math.Sqrt returns a double.
Here is the signature from the documentation:
public static double Sqrt (double d);
So you try to put a double into an int (the type of your square_root variable), which is only possible with an explicit cast, hence the compiler message.
To fix this (supposing you want to keep a non integer value for the square root) simply correct the line with
double square_root = Math.Sqrt(number);
or you can even let the compiler do the work by leveraging the var keyword:
var square_root = Math.Sqrt(number);
Additional remarks:
The Math.Sqrt signature shows that a double is needed as parameter, but you pass an int. This is not a problem since the compiler can do an implicit conversion from an int to a double.
There will also be an error on the following line (without even considering the meaning of what you write).
Console.WriteLine("$The square root of {square_root} is " , square_root);
To concatenate strings, you can use several techniques, like composite formating and string interpolation. It seems you mix both synthax on this line.
See the string interpolation documentation:
an example of both methods taken from the documentaion:
string name = "Mark";
var date = DateTime.Now;
// Composite formatting:
Console.WriteLine("Hello, {0}! Today is {1}, it's {2:HH:mm} now.", name, date.DayOfWeek, date);
// String interpolation:
Console.WriteLine($"Hello, {name}! Today is {date.DayOfWeek}, it's {date:HH:mm} now.");
// Both calls produce the same output that is similar to:
// Hello, Mark! Today is Wednesday, it's 19:40 now.

Convert.ToInt64 fails when value is "0.00000"

5 my code is like this
protected long Getvalue()
{
DataTable dt = GetDataBaseValue();
if (dt.Rows.Count > 0)
{
return Convert.ToInt64(dt.Rows[0]["BALANCE"].ToString());
}
return 0;
}
dt.Rows[0]["BALANCE"].ToString()=0.00000 I am getting the error here
PS: I tried to do this return long.Parse(...) and I got the same error
The problem is that "0.00000" is a String, which is an invalid format for "parsing to a long"1.
However, it may be sufficient to omit the ToString() conversion, and thus the above error, depending on what type the database actually returns. If the database returns an appropriate double/float/decimal then the following "Will Work", even if losing precision.
// Source is a double
Convert.ToInt64(0.0d) // -> 0
Convert.ToInt64(0.5d) // -> 0 (half-even rounding)
Convert.ToInt64(1.5d) // -> 2 (half-even rounding)
Convert.ToInt64(double.MaxValue) // -> OverflowException
// Source is a string
Convert.ToInt64("0") // -> 0
Convert.ToInt64("0.0") // -> FormatException: "not in a correct format"
If, for some uncorrectable reason, the database returns a String in the given format, it should suffice to first convert the string to a double/decimal (which do support such a format) and then to a long. Similar overflow and loss of precision cases are possible.
long v = (long)Convert.ToDecimal(dt.Rows[0]["BALANCE"]);
By default, .NET will parse integer values (e.g. int, long) from strings only when they conform to the pattern \s*[-+]?\d+\s* and will throw a FormatException otherwise; this is discussed in more detail in the linked documentation.
0.00000 is not a valid value for Int64. Perhaps you intended to use a Decimal (it looks like a currency amount) or otherwise truncate/round the value first?
Use Decimal.Parse("0.0000"); this is used for currency Not Long or Int64

Function Int32.TryParse("23.0") returning false - C# MVC4

In my code i try to get browser version for charging the good css file, but this code doesn't work, and i don't see my error...
I've simply try first with a Convert.ToInt32 but don't works too...
public ActionResult Index()
{
ViewBag.logged = false;
ViewBag.BrowserName = Request.Browser.Browser.ToString();
Int32 v = 0;
string version = Request.Browser.Version;
if (version != null)
{
bool result = Int32.TryParse(version, out v);
}
ViewBag.BrowserVersion = v;
return View();
}
In my debugger :
version => string : "23.0"
v => int 0
result => false
Request.Browser.Version => string "23.0"
This is by design.
Parsing a version string would work better with System.Version.
You can, alternatively, parse it to a float and then see if a lossless conversion to Int32 can be made.
I fully agree with Andrei's answer; that's the approach you should take.
However, I think it's important to note that there is a way to parse int values from strings such as "23.0": it can be done using this overload of int.TryParse() which allows you to pass NumberStyles flags as parameters.
Concretely, after executing this code:
int v;
var wasParsedOK = Int32.TryParse(
"23.0",
NumberStyles.AllowDecimalPoint,
CultureInfo.InvariantCulture,
out v);
v will hold the value 23 and wasParsedOK will be true.
You can't assume that the version string is going to be integral, or even decimal. A browser could perfectly report 7.0b as its version. None of int, float, decimal or System.Version can represent this.
If you're only concerned about the major and minor version numbers, you can use the MajorVersion and MinorVersion properties of your Browser object, assuming it is of type HttpBrowserCapabilities. The framework has done the parsing for you, so it should be reliable.
It is giving false because 23.0 is not an int, So you can try with decimal,double or float.
decimal v = 0;
string version = "23.0";
Decimal.TryParse(version, out v);
It's been almost 2 years and no one has answered this correctly. The question is simple, "Why is it returning false?"
This question has already been answered, simply because your string is not an Integer, but is a Double or Decimal. By design, TryParse will try to get the EXACT match of the type integer from your string, if not it will return false, and your string ("23.0") is not an exact match.
Now if you're trying to find a solution in converting your version string to a number, What you can do is filter out the non-numeric, excluding 1 dot (.), in the string, then convert what's left to decimal/double. After this conversion you can then try converting it integer. Since you already converted your stirng to double/decimal, you can no longer use TryParse because the parameter needs to be in string format. You can then use Convert.ToInt32 inside a Try block.

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
}

Error: Specified cast is not valid while converting decimal to double

I have a function as under
private double RoundOff(object value)
{
return Math.Round((double)value, 2);
}
And I am invoking it as under
decimal dec = 32.464762931906M;
var res = RoundOff(dec);
I am gettingthe below error
Specified cast is not valid
What is the mistake?
Thanks
Casting the object to double will attempt to unbox the object as a double, but the boxed object is a decimal. You need to convert it to a double after first unboxing it. Then you perform the rounding:
Math.Round((double)(decimal)value, 2);
The other answers are correct in terms of getting something that will run - but I wouldn't recommend using them.
You should almost never convert between decimal and double. If you want to use a decimal, you should use Math.Round(decimal). Don't convert a decimal to double and round that - there could easily be nasty situations where that loses information.
Pick the right representation and stick with it. Oh, and redesign RoundOff to not take object. By all means have one overload for double and one for decimal, but give them appropriate parameter types.
As an alternative to John's answer, if you want to use other number types than just decimal, you could use this code;
private double RoundOff(object value)
{
return Math.Round(Convert.ToDouble(value), 2);
}

Categories

Resources