In C# can I cast a variable of type object
to a variable of type T
where T
is defined in a Type
variable?
Type
variable, you can use reflection to create an instance of that type. And then you can use a generic method to return the type you want by inferring it from a parameter of that type. Unfortunately, any reflection method that creates an instance of a type will have a return type of object
, so your generic CastByExample
method will use object
as well. So there's really no way to do this, and even if there was, what would you do with the newly-cast object? You couldn't use its methods or anything because you don't know its type.
object
or dynamic
. If you want to dynamically load external modules, you can have the classes share a common interface and cast the object to that. If you don't control the third party code, create small wrappers and implement the interface on that.
Here is an example of a cast and a convert:
using System;
public T CastObject<T>(object input) {
return (T) input;
}
public T ConvertObject<T>(object input) {
return (T) Convert.ChangeType(input, typeof(T));
}
Edit:
Some people in the comments say that this answer doesn't answer the question. But the line (T) Convert.ChangeType(input, typeof(T))
provides the solution. The Convert.ChangeType
method tries to convert any Object to the Type provided as the second argument.
For example:
Type intType = typeof(Int32);
object value1 = 1000.1;
// Variable value2 is now an int with a value of 1000, the compiler
// knows the exact type, it is safe to use and you will have autocomplete
int value2 = Convert.ChangeType(value1, intType);
// Variable value3 is now an int with a value of 1000, the compiler
// doesn't know the exact type so it will allow you to call any
// property or method on it, but will crash if it doesn't exist
dynamic value3 = Convert.ChangeType(value1, intType);
I've written the answer with generics, because I think it is a very likely sign of code smell when you want to cast a something
to a something else
without handling an actual type. With proper interfaces that shouldn't be necessary 99.9% of the times. There are perhaps a few edge cases when it comes to reflection that it might make sense, but I would recommend to avoid those cases.
Edit 2:
Few extra tips:
Try to keep your code as type-safe as possible. If the compiler doesn't know the type, then it can't check if your code is correct and things like autocomplete won't work. Simply said: if you can't predict the type(s) at compile time, then how would the compiler be able to?
If the classes that you are working with implement a common interface, you can cast the value to that interface. Otherwise consider creating your own interface and have the classes implement that interface.
If you are working with external libraries that you are dynamically importing, then also check for a common interface. Otherwise consider creating small wrapper classes that implement the interface.
If you want to make calls on the object, but don't care about the type, then store the value in an object or dynamic variable.
Generics can be a great way to create reusable code that applies to a lot of different types, without having to know the exact types involved.
If you are stuck then consider a different approach or code refactor. Does your code really have to be that dynamic? Does it have to account for any type there is?
Other answers do not mention "dynamic" type. So to add one more answer, you can use "dynamic" type to store your resulting object without having to cast converted object with a static type.
dynamic changedObj = Convert.ChangeType(obj, typeVar);
changedObj.Method();
Keep in mind that with the use of "dynamic" the compiler is bypassing static type checking which could introduce possible runtime errors if you are not careful.
Also, it is assumed that the obj is an instance of Type typeVar or is convertible to that type.
Here is my method to cast an object but not to a generic type variable, rather to a System.Type
dynamically:
I create a lambda expression at run-time using System.Linq.Expressions
, of type Func<object, object>
, that unboxes its input, performs the desired type conversion then gives the result boxed. A new one is needed not only for all types that get casted to, but also for the types that get casted (because of the unboxing step). Creating these expressions is highly time consuming, because of the reflection, the compilation and the dynamic method building that is done under the hood. Luckily once created, the expressions can be invoked repeatedly and without high overhead, so I cache each one.
private static Func<object, object> MakeCastDelegate(Type from, Type to)
{
var p = Expression.Parameter(typeof(object)); //do not inline
return Expression.Lambda<Func<object, object>>(
Expression.Convert(Expression.ConvertChecked(Expression.Convert(p, from), to), typeof(object)),
p).Compile();
}
private static readonly Dictionary<Tuple<Type, Type>, Func<object, object>> CastCache
= new Dictionary<Tuple<Type, Type>, Func<object, object>>();
public static Func<object, object> GetCastDelegate(Type from, Type to)
{
lock (CastCache)
{
var key = new Tuple<Type, Type>(from, to);
Func<object, object> cast_delegate;
if (!CastCache.TryGetValue(key, out cast_delegate))
{
cast_delegate = MakeCastDelegate(from, to);
CastCache.Add(key, cast_delegate);
}
return cast_delegate;
}
}
public static object Cast(Type t, object o)
{
return GetCastDelegate(o.GetType(), t).Invoke(o);
}
Note that this isn't magic. Casting doesn't occur in code, as it does with the dynamic
keyword, only the underlying data of the object gets converted. At compile-time we are still left to painstakingly figure out exactly what type our object might be, making this solution impractical. I wrote this as a hack to invoke conversion operators defined by arbitrary types, but maybe somebody out there can find a better use case.
using System.Linq.Expressions;
Type t = typeof(MyGeneric<>).MakeGenericType(obj.OutputType); var a = (t)Convert.ChangeType(obj, t); var b = (t)Caster.Cast(t, obj);
Type
. You can't cast using normal casting syntax if all you have is the Type object. If you want to be able to use the object as some type T at compile time, not runtime, you need to cast it using a type variable or just the actual type name. You can do the former using Zaphrax's answer.
Putting boxing and unboxing aside for simplicity, there's no specific runtime action involved in casting along the inheritance hierarchy. It's mostly a compile time thing. Essentially, a cast tells the compiler to treat the value of the variable as another type.
What you could do after the cast? You don't know the type, so you wouldn't be able to call any methods on it. There wouldn't be any special thing you could do. Specifically, it can be useful only if you know the possible types at compile time, cast it manually and handle each case separately with if
statements:
if (type == typeof(int)) {
int x = (int)obj;
DoSomethingWithInt(x);
} else if (type == typeof(string)) {
string s = (string)obj;
DoSomethingWithString(s);
} // ...
How could you do that? You need a variable or field of type T where you can store the object after the cast, but how can you have such a variable or field if you know T only at runtime? So, no, it's not possible.
Type type = GetSomeType();
Object @object = GetSomeObject();
??? xyz = @object.CastTo(type); // How would you declare the variable?
xyz.??? // What methods, properties, or fields are valid here?
CastTo
method on Object
?
After not finding anything to get around "Object must implement IConvertible" exception when using Zyphrax's answer (except for implementing the interface).. I tried something a little bit unconventional and worked for my situation.
Using the Newtonsoft.Json nuget package...
var castedObject = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(myObject), myType);
When it comes to casting to Enum type:
private static Enum GetEnum(Type type, int value)
{
if (type.IsEnum)
if (Enum.IsDefined(type, value))
{
return (Enum)Enum.ToObject(type, value);
}
return null;
}
And you will call it like that:
var enumValue = GetEnum(typeof(YourEnum), foo);
This was essential for me in case of getting Description attribute value of several enum types by int value:
public enum YourEnum
{
[Description("Desc1")]
Val1,
[Description("Desc2")]
Val2,
Val3,
}
public static string GetDescriptionFromEnum(Enum value, bool inherit)
{
Type type = value.GetType();
System.Reflection.MemberInfo[] memInfo = type.GetMember(value.ToString());
if (memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), inherit);
if (attrs.Length > 0)
return ((DescriptionAttribute)attrs[0]).Description;
}
return value.ToString();
}
and then:
string description = GetDescriptionFromEnum(GetEnum(typeof(YourEnum), foo));
string description2 = GetDescriptionFromEnum(GetEnum(typeof(YourEnum2), foo2));
string description3 = GetDescriptionFromEnum(GetEnum(typeof(YourEnum3), foo3));
Alternatively (better approach), such casting could look like that:
private static T GetEnum<T>(int v) where T : struct, IConvertible
{
if (typeof(T).IsEnum)
if (Enum.IsDefined(typeof(T), v))
{
return (T)Enum.ToObject(typeof(T), v);
}
throw new ArgumentException(string.Format("{0} is not a valid value of {1}", v, typeof(T).Name));
}
int value = 3; var yourEnum = (YourEnum) value;
I will never understand why you need up to 50 reputation to leave a comment but I just had to say that @Curt answer is exactly what I was looking and hopefully someone else.
In my example, I have an ActionFilterAttribute that I was using to update the values of a json patch document. I didn't what the T model was for the patch document to I had to serialize & deserialize it to a plain JsonPatchDocument, modify it, then because I had the type, serialize & deserialize it back to the type again.
Type originalType = //someType that gets passed in to my constructor.
var objectAsString = JsonConvert.SerializeObject(myObjectWithAGenericType);
var plainPatchDocument = JsonConvert.DeserializeObject<JsonPatchDocument>(objectAsString);
var plainPatchDocumentAsString= JsonConvert.SerializeObject(plainPatchDocument);
var modifiedObjectWithGenericType = JsonConvert.DeserializeObject(plainPatchDocumentAsString, originalType );
public bool TryCast<T>(ref T t, object o)
{
if (
o == null
|| !typeof(T).IsAssignableFrom(o.GetType())
)
return false;
t = (T)o;
return true;
}
If you need to cast objects at runtime without knowing destination type, you can use reflection to make a dynamic converter.
This is a simplified version (without caching generated method):
public static class Tool
{
public static object CastTo<T>(object value) where T : class
{
return value as T;
}
private static readonly MethodInfo CastToInfo = typeof (Tool).GetMethod("CastTo");
public static object DynamicCast(object source, Type targetType)
{
return CastToInfo.MakeGenericMethod(new[] { targetType }).Invoke(null, new[] { source });
}
}
then you can call it:
var r = Tool.DynamicCast(myinstance, typeof (MyClass));
even cleaner:
public static bool TryCast<T>(ref T t, object o)
{
if (!(o is T))
{
return false;
}
t = (T)o;
return true;
}
Success story sharing
T
as such.Convert.ChangeType(input, typeof(T));
gives the solution. You can easily replacetypeof(T)
with an existing type variable. A better solution (if possible) would be to prevent the dynamic type all together.T
which is not available.T
but still you only get anobject
as a reference. hmm, I found the question interesting in the premise that OP has only theType
variable and no other info. As if the method signature isConvert(object source, Type destination)
:) Nevertheless i get ur point