Detecting a Nullable Type via reflection - c#

Surprisingly the following code fails the Assert:
int? wtf = 0;
Assert.IsType<Nullable<int>>(wtf);
So just out curiosity, how can you determine if a given instance is a Nullable<> object or not?

Well firstly, Nullable<T> is a struct, so there isn't an object as such. You can't call GetType(), as that will box the value (at which point you either get null and thus an exception, or a boxed non-nullable value and therefore not the type you want).
(Boxing is what's messing up your assertion here - I would assume that IsType accepts object.)
You can use type inference though to get the type of the variable as a type parameter:
public bool IsNullable<T>(T value)
{
return Nullable.GetUnderlyingType(typeof(T)) != null;
}
That's not a huge amount of use when you know the exact type at compile-time as in your example, but it's useful for generics. (There are alternative ways of implementing it, of course.)
What's your real life situation? I assume it's not an assertion like this, given that you know the answer to this one at compile time.

I like the #jon-skeet answer but it only works if you know the type you are testing against. In our world we are using reflection to open up objects and test values against regex expressions.
simplifying the extension to work for any type worked better for us.
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
generics are life's blood but sometimes... :)

int? i = 0;
var type = TypedReference.GetTargetType(__makeref(i));
var isNullable = type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>);

What namespace is Assert in?
The following returns true as you would expect:
int? wtf = 0;
if (typeof(Nullable<int>).IsInstanceOfType(wtf))
{
// Do things
}
Although its worth noting that typeof(Nullable<int>).IsInstanceOfType(42) also returns true - this is because this method accepts an object and so gets boxed as a Nullable<int>.

Here is what I came up with, as everything else seemed to fail - at least on Portable Class Library / DotNet Core with >= C# 6
Basically you extend generic Type Object and Nullable<T> and use the fact that the static extension method that matches the underlying type is going to be invoked and takes precedence over the generic T extension-method.
public static partial class ObjectExtension
{
public static bool IsNullable<T>(this T self)
{
return false;
}
}
and one for Nullable<T>
public static partial class NullableExtension
{
public static bool IsNullable<T>(this Nullable<T> self) where T : struct
{
return true;
}
}
Using Reflection and type.IsGeneric and type.GetGenericParameters() did not work on my current set of .NET Runtimes.

It works fo me, hope for you too.
public static bool IsNullable(this Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}

Based on Vladimir answer:
public static class GenericExtensions
{
public static bool IsNullable<T>(this T item) =>
TypedReference.GetTargetType(__makeref(item)).FullName.Contains("System.Nullable");
}
Usage:
int? nullableInt = 42;
bool nIntIsNullable = nullableInt.IsNullable();
Duration: <2ms on average machine.
Remarks:
Important, this API is not CLS-compliant.
Contains("System.Nullable") can be more specific.

This works for me to check wether a type is Nullable or not..
type.Assembly.FullName.StartsWith("System") && type.Name.Contains("Nullable");

Only this way worked in my case using .net core 7
MyClass mclass = new MyClass();
PropertyInfo[] properties = mclass.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in properties)
{
bool nullable = propertyInfo.GetMethod is null ? false : new NullabilityInfoContext().Create(propertyInfo.GetMethod.ReturnParameter).ReadState == NullabilityState.Nullable;
if (nullable)
{
//some script to do
}
}

Related

Derived Types and Generics

I have a type that uses generics. Let's call it FlowerDescriptor<T> some flowers are described using numbers, others using strings etc.
so FlowerDescriptor<int>; FlowerDescriptor<string>; etc
I want a mechanism (probably extension methods) for doing 2 things
seeing if something is a FlowerDescriptor and
seeing what the descriptor is.
I.e.
FlowerDescriptor<string>.GetType().IsFlowerDescriptor == true
string.GetType().IsFlowerDescriptor == false.
equally I might derive from FlowerDescriptor<int> i.e. class NumberedFlower: FlowerDescriptor<int>
new NumberedFlower.GetType().IsFlowerDesriptor == true;
as above but returns the type
FlowerDescriptor<string>.GetType().GetFlowerDescriptor() == typeof(string)
FlowerDescriptor<int>.GetType().GetFlowerDescriptor() == typeof(int)
new NumberedFlower.GetType().GetFlowerDescriptor() == typeof(int)
I have played about with variations of IsAssignableFrom and it feels like that ought to work with typeof(FlowerDescriptor<>).IsAssignableFrom(typeof(FlowerDescriptor<string>))
but it doesn't work. If it add the generic type however it does.
I am currently exploring GetInterfaces to know available interfaces. It'd be great to actually understand what I am doing wrong too..
Unless you want to add interfaces into the mix, the only choice you have is to
Detect that the type is actually a FlowerDescriptor<T>
or detect that the type inherits from something that is a FlowerDescriptor<T>
Unfortunately I don't think you can use IsAssignableFrom when it comes to open generics which means we're left with walking the inheritance chain up to the base classes.
Here is an example piece of code that would do the right thing:
public static bool IsFlowerDescriptor(this Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(FlowerDescriptor<>))
return true;
if (type.BaseType != null)
return type.BaseType.IsFlowerDescriptor();
return false;
}
Here's a .NET Fiddle you can experiment with.
I would not expect the string or int class to know if its a descriptor, it makes a lot more sense to get that information from the FlowerDescriptor.
That being said if you want to use reflection you could get the generic type definition from the FlowerDescriptor instance
FlowerDescriptor<int> f = new FlowerDescriptor<int>();
Type t = f.GetType();
Type[] typeArguments = t.GetGenericArguments();
//check if type you care about is in typeArguments
Here is how you would get those two values:
bool isFlowerDescriptor = x is FlowerDescriptor<object>;
Type descriptorType = x.GetType().GetGenericArguments()[0];
You could wrap these in extension methods if you like. And add null-checks etc.
You might consider having a non-generic base class. Then your structure could look like:
public abstract class FlowerDescriptor { }
public class FlowerDescriptor<T> : FlowerDescriptor { }
public class NumberedFlower : FlowerDescriptor<int> { }
Your 2 extensions would be:
public static class Extensions
{
public static bool IsFlowerDescriptor(this object o)
{
return o is FlowerDescriptor;
}
public static Type GetFlowerDescriptor<T>(this FlowerDescriptor<T> o)
{
return typeof (T);
}
}
and you'd use it like:
public static void Main()
{
Console.WriteLine(new NumberedFlower().IsFlowerDescriptor()); //true
Console.WriteLine(new NumberedFlower().GetFlowerDescriptor()); //System.Int32
}
Generics have an adverse effect when it comes to reflecting over and comparing types, because a FlowerDescriptor<int> is a different type from FlowerDescriptor<string>. This is something I have not found a good rhythm for.

Downcast an object to type specified in a "Type" variable [duplicate]

In C# can I cast a variable of type object to a variable of type T where T is defined in a Type variable?
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.
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);
} // ...
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);
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?
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));
}
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;
}

Most efficient way to check if an object is a value type

WARNING: THIS CODE SUCKS, SEE ANTHONY'S COMMENTS
Which is faster?
1.
public bool IsValueType<T>(T obj){
return obj is ValueType;
}
2.
public bool IsValueType<T>(T obj){
return obj == null ? false : obj.GetType().IsValueType;
}
3.
public bool IsValueType<T>(T obj){
return default(T) != null;
}
4.Something else
You aren't really testing an object - you want to test the type. To call those, the caller must know the type, but... meh. Given a signature <T>(T obj) the only sane answer is:
public bool IsValueType<T>() {
return typeof(T).IsValueType;
}
or if we want to use an example object for type inference purposes:
public bool IsValueType<T>(T obj) {
return typeof(T).IsValueType;
}
this doesn't need boxing (GetType() is boxing), and doesn't have problems with Nullable<T>. A more interesting case is when you are passing object...
public bool IsValueType(object obj);
here, we already have massive problems with null, since that could be an empty Nullable<T> (a struct) or a class. But A reasonable attempt would be:
public bool IsValueType(object obj) {
return obj != null && obj.GetType().IsValueType;
}
but note that it is incorrect (and unfixable) for empty Nullable<T>s. Here it becomes pointless to worry about boxing as we are already boxed.
My first answer would be to write a simple test and find out for yourself.
My second answer (without any testing on my part, of course) would be option 1. It is the simplest check. The second method involves two separate checks while the third involves creating a default instance of a type.
You should also consider readability. The framework already gives you the ability to have the following in your code:
if(someObj is ValueType)
{
// Do some work
}
Why even bother creating a method that would simply turn the above statement into (assuming you made your method static and allowed the compiler to infer the generic type):
if(IsValueType(someObj))
{
// Do some work
}
Defining a struct actually defines two types: a value type, and a class type which derives from System.ValueType. If a request is made to create a variable, parameter, field, or array (collectively, 'storage location') of a type which derives from System.ValueType, the system will instead create a storage location which will store the object's fields rather than storing a reference to an object in which those fields appear. On the other hand, if a request is made to create an instance of a type deriving from System.ValueType, the system will create an object instance of a class which derives from System.ValueType.
This may be demonstrated by creating a struct which implements IValue:
interface IValue {int value {get; set;}};
struct ValueStruct : IValue
{
public int value {get; set;}};
}
with generic test routine and code to wrap it:
static void Test<T>(T it) where T:IValue
{
T duplicate = it;
it.value += 1;
duplicate.value += 10;
Console.WriteLine(it.value.ToString());
}
static void Test()
{
ValueStruct v1 = new ValueStruct();
v1.value = 9;
IValue v2 = v1;
Test<ValueStruct>(v1);
Test<ValueStruct>(v1);
Test<IValue>(v1);
Test<IValue>(v1);
Test<IValue>(v2);
Test<IValue>(v2);
}
Note that in every case, calling GetType on the parameter passed to Test would yield ValueStruct, which will report itself as a value type. Nonetheless, the passed-in item will only be a "real" value type on the first two calls. On the third and fourth calls, it will really be a class type, as demonstrated by the fact that a change to duplicate will affect it. And on the fifth and sixth calls, the change will be propagated back to v2, so the second call will "see" it.
static class Metadata<T>
{
static public readonly Type Type = typeof(T);
static public readonly bool IsValueType = Metadata<T>.Type.IsValueType;
}
//fast test if T is ValueType
if(Metadata<T>.IsValueType) //only read static readonly field!
{
//...
}
There are two rules:
1-All Classes are reference types such as Object and String, so it's supported by .NET Framework classes.
2-All structures are value types such as bool and char, even though it contain reference member, so it's supported by .NET Framework structures.
Simply right click on any type and Go To Definition if it's a Class so that means it a reference type else if it's a Struct so that means it's a value type :)
You can use
obj.GetType().IsValueType
This uses reflection but clear way instead of care of boxing unboxing.

Nullable primitives with Generics

I'm trying to find the right thing to do with a non-null validation on a nullable boolean. I also want to be able to do the same thing with some other fields, including strings, ints, etc., so I want to use generics for the method. Here's an example of the kind of thing which can happen.
bool? myValue = null;
bool valid = ValidateNotNull(myValue);
And here's some validation code:
public bool ValidateNotNull<T>(T nullableField)
{
return nullableField != null;
}
All the answers I've found to this kind of problem suggest adding a where T : struct or where T: class to the method signature, or using default(T) in the comparison, none of which will work for a bool where false is a valid value.
Any other suggestions? The code compiles, but Resharper isn't happy about that null comparison on a value which it thinks might be a primitive, and I'd love to know what I should be doing to cheer it up.
NB: This isn't the complete code. I'm still interested in maintaining the type. This is also not the only place I've run into the problem.
NB2: Yes, it compiles and works fine. What I really want to know is whether there is a code solution for stopping Resharper from complaining, or an idiomatic way to do this which I don't know about.
The code below will validate nullable types and reference types:
public bool ValidateNotNull<T>(Nullable<T> nullableField) where T:struct
{
return nullableField.HasValue;
}
public bool ValidateNotNull<T>(T nullableField) where T:class
{
return nullableField!=null;
}
Would comparing to default work?
public bool ValidateNotNull<T>(T nullableField)
{
return Equals(nullableField, default(T));
}
Updated:
Either its a primitive, and all is well, or its not null:
public bool ValidateNotNull<T>(T nullableField)
{
return typeof(T).IsPrimitive || !Equals(nullableField, null);
}
I also want to be able to do the same thing with some other fields, including strings, ints, etc
OK, so you want a method that can be passed either a Nullable<> (which is a struct), or a reference type, and will return true iff the argument is null (note that your name appears to be the wrong way round, but there you go).
The thing is, if that's all this method has to do, then you don't need generics because you don't need type-safety. This example works and does what you want, I think:
class Program
{
static void Main(string[] args)
{
int? x = null;
int? y = 5;
string s = null;
string r = "moo";
Console.WriteLine(ValidateNotNull(x));
Console.WriteLine(ValidateNotNull(y));
Console.WriteLine(ValidateNotNull(s));
Console.WriteLine(ValidateNotNull(r));
Console.ReadLine();
}
private static bool ValidateNotNull(object o)
{
return o == null;
}
}
This outputs
True
False
True
False
which is I believe your required output.
I don't know why you thing your method doesn't work (apart from using != rather than ==), because as far as I can tell, it already works! You can compare any value of type T with null (when T is a generic type parameter). If a non-nullable value type is used for T, the result will be treated as a constant (false for == null, true for != null).
So, this should be fine.
public bool ValidateNotNull<T>(T nullableField)
{
return nullableField != null;
}
But this would also work without generics:
public bool ValidateNotNull(object nullableField)
{
return nullableField != null;
}
(Because boxing a Nullable<T> null value returns a null reference.)
You need to use
public bool ValidateNotNull<T>(T nullableField)
{
return nullableField.HasValue;
}

Casting a variable using a Type variable

In C# can I cast a variable of type object to a variable of type T where T is defined in a Type variable?
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.
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);
} // ...
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);
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?
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));
}
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;
}

Categories

Resources