Reputation: 580
An object value from a third party application provides a value that is correct but incorrectly typed. I'm trying to Type this object value in an generic method i'm creating into the type of my choosing. I've mocked up an example to demonstrate the problem.
static void Main(string[] args)
{
decimal d = 1; // this can't be changed
var v = Method<int>(d); // what I'm trying to do
}
//the code in this method can be changed
static T Method<T>(object input)
{
T output = default(T);
//causes InvalidCastException
output = (T)input;
return output;
}
As you can see the value '1' is an valid integer, however as the third party application types it as a decimal, when trying to convert it to an integer it falls over. How can the generic method be changed so that it can won't fall over for this scenario?
Upvotes: 2
Views: 106
Reputation: 203827
"Casting" and "Converting" are two very different things. Unfortunately, in certain instances the syntax in C# is the same, so that can confuse the topic.
input
can only be cast to a decimal
, since that's what it really is. You can convert a decimal
to an int
, but you can't convert and object
that happens to contain a decimal
to an int
.
So if you do:
static int ToInt(object input)
{
return (int)(decimal)input;
}
Then it will work.
If you want to handle the general case where there is a conversion operator from whatever input
is to T
then you're pretty much out of luck. Those conversions are compile time mechanisms, not runtime mechanisms.
Upvotes: 1
Reputation: 14767
Try something like this:
static T Method<T>(object input)
{
T output = default(T);
var t = input.GetType();
TypeConverter tc = TypeDescriptor.GetConverter(t);
output = (T)tc.ConvertTo(input, typeof(T));
return output;
}
Obviously you'd want to add some error checking to make sure the types are compatible -- look at the methods on TypeConverter.
You'll need to add a using System.ComponentModel;
Upvotes: 1
Reputation: 8679
Replace output = (T)input;
with:
output = (T)Convert.ChangeType(input, typeof(T));
Upvotes: 2