I get the following error when trying to convert an object to float:
System.InvalidCastException: The cast specified is invalid.
menu[i].weight = (float)dataGridView1[j, i].Value;
CodePudding user response:
You can use float.TryParse and pass object convert ToString() as parameter. Please see below.
object obj = 2.111;
float height;
if (float.TryParse(obj.ToString(), out height))
{
//success
Console.WriteLine(height);
}
else
{
//failed
}
CodePudding user response:
The value you're converting, as others have stated in the comments, is not truly a float - but that might be confusing, because it might look like a float - here's an example of a possible scenario:
object maybeFloat = 1.25; // looks like a float, but is actually a double!
float wontWork = (float)maybeFloat;
The above cast will fail, throwing an InvalidCastException - because the actual item stored (technically known in C# as boxed, in the case of structs, such as int, float, double, as well as custom struct types) is a double, not a float. There are several "fixes":
- Store a float:
object someFloat = 1.25f; // Notice the `f` after the number - that's a float!
float willWork = (float)someFloat;
... but that's not always possible - the data might be coming from some external source, such as a database, etc. In that case, float.Parse to the rescue:
object maybeFloat = 1.25; // Still not a float... but can be parsed as one!
float willWork = float.Parse(maybeFloat.ToString()); // float.Parse requires a string,
// hence the `.ToString()` call
This will work if the object contains a value that is in fact parseable into a float datatype. So, the above example works for parsing a boxed double into a float (notice, some data loss may occur - not in the above example, but in general, because float is a smaller data type than double). This will also work if the value stored is a string (as an aside, strings are not boxed, because they are reference types). Perhaps strangely, the .ToString() call is still required - because there is no implicit conversion from object to string:
object maybeFloat = "1.25"; // Still not a float... but can be parsed as one!
float willWork = float.Parse(maybeFloat.ToString()); // no implicit conversion,
// hence the `.ToString()` call
... but what if the value stored is really, really, not a float at all? Well, then float.Parse will fail, most likely throwing a FormatException, indicating that the supplied value is really not parseable into a float datatype. You can catch the exception with a try/catch block:
object maybeFloat = "one point two five"; // hmmm... that won't parse into a float!
float result = default;
try
{
result = float.Parse(maybeFloat.ToString());
}
catch (FormatException _)
{
// Handle error here!
}
...however, there's a better way - float.TryParse:
object maybeFloat = "one point two five"; // will fail to parse!
bool isSuccessfullyParsed = float.TryParse(maybeFloat.ToString(), out var result);
if (!isSuccessfullyParsed)
{
// Handle error
}
else
{
// `result` will contain the properly parsed float value
}
Ok, this should give you a pretty good idea of what's happening in your specific case. Final note, the .Parse and .TryParse methods exist on all .NET numeric types - int, long, float, double, decimal, even BigInteger - so same technique applies to all of them.
