I Decided To Test My Script On Integers And It Gives Me An Error:
Cannot cast from source type to destination type.
And I Know What It Means And How To Solve It, However In My Script The Returning Value Is Unknown If It’s Int Or Float! And I Want It To Work For Both Float And Int! So I Want To Do Something Like This:
value = (float)(int)source.GetType().GetField(valueName).GetValue(source);
Originally It’s Like This Now:
value = (float)source.GetType().GetField(valueName).GetValue(source);
The (value) Is A Float, And The Returning Value Might Be An Int, So It Throws Errors! Is There A Way To Cast On The Returning Value 2 Times? If I Change It To (Int), Then If The Returning Value Is A Float, It Gives Me The Same Error!
Thanks…
You can get the type you want by just delving a little deeper into reflection.
You should create a generic method where you pass in the type you want and the method works it out for you. However, you really should know the type in advance because otherwise subsequent code cannot be written safely to deal with it.
public T GetValue<T>(object valueObject, string fieldName)
{
var valueObjectType = valueObject.GetType();
var valueObjectField = valueObjectType.GetField(fieldName);
if (valueObjectField != null)
{
var value = valueObjectField.GetValue(valueObject);
if (value.GetType() == typeof(T)) return (T)value;
}
throw new InvalidCastException("value is not of expected type T");
}
This will accept a Type (T) and return a value of Type T if it can read the value into that given type.
For example:
var value = GetValue<float>(myObject, fieldName);
This will return a float because you’ve asked for one in the <>. This is better than just trying to cast to every different type.
public float CastToFloatOrInt(string value)
{
// Try float first
float data;
if (float.TryParse(value, out data))
{
return data;
}
// Try int next if float doesn't work
int data2;
if (int.TryParse(value, out data2))
{
return data2;
}
// If not float or int can be cast throw exception
throw new System.Exception("Error cannot cast " + value + " to float or int");
}
Try something like this. Will always return a float, but it will be able to cast ints to float too.
You might have to cast to string first before you pass it to the method.
Not with a cast, no. There are three seperate things that can be performed with a cast:
A plain type cast, only relevant for reference types
Unboxing a boxed primitive type
An explicit type conversion
In your case you want to perform the last two things at the same time which doesn’t work since they do two seperate thing. Unboxing a boxed primitive type only works when you specify the actual type. Once unboxed it can be converted. This is what (float)(int) does. You unbox a boxed integer value and then convert it to float.
The most common alternative when using reflection is to use Convert.ChangeType. It’s able to do a type conversion on a boxed value type. This way you can always convert the value into float and then unbox the float
object o = source.GetType().GetField(valueName).GetValue(source);
float value = (float)Convert.ChangeType(o, typeof(float));
This should work with any type that can be explicitly converted into float (byte, short, int, long, double, …).
So if I am understanding this correctly, you are trying to take a value that you are uncertain as to its type (int or float) and trying to store it, correct? If so, you may want to make use of the C# implicit type var.
So using the example you gave, use:
var value = source.GetType().GetField(valueName).GetValue(source);
Then you should be able to use value.GetType() to find out its type and then cast accordingly.