-1

In C#, if I have a variable of type object, how can I check if I can cast it to a type T which is a value type? The as operator doesn't work, since T is a value type, and o.GetType().Equals(typeof(T)) just checks if object is a boxed variable of type T, but not if it is something that can be cast to T.

matthias_buehlmann
  • 4,641
  • 6
  • 34
  • 76
  • "...just checks if object is a boxed variable of type T, but not if it is something that can be cast to T." For structs, aren't these two things equivalent? Can you give an example of such a `T`, i.e. `o.GetType().Equals(typeof(T))` is false, but you can cast the object to `T`. – Sweeper Aug 16 '20 at 13:06
  • @Sweeper no, if it's a boxed float it would return a different result than for a boxed double, even though both can be cast to either one – matthias_buehlmann Aug 16 '20 at 13:08
  • 4
    @user1282931: No, a boxed `double` can't be cast to `float` or vice versa. There are a *few* cases where you can cast to a different type (e.g. `uint` vs `int`, or enums) but in general, you can only unbox to the original boxed type. – Jon Skeet Aug 16 '20 at 13:09
  • 2
    @user1282931 Can you use the `is` operator like `if (o is double d)`? – Progman Aug 16 '20 at 13:09
  • 1
    Umm... no, you can't cast a boxed `float` to `double`. Try `object o = 1f; double d = (double)o;`. Unless you mean something different? – Sweeper Aug 16 '20 at 13:09
  • @JonSkeet What do you mean by `uint` vs `int`? Casting a boxed `int` to `uint` or viceversa throws `InvalidCastException`. – V0ldek Aug 16 '20 at 13:13
  • I would assume that `as` would not work even if `T` was reference type, cause _The as operator considers only reference, nullable, boxing, and unboxing conversions. You cannot use the as operator to perform a user-defined conversion._ ([docs](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator)) – Guru Stron Aug 16 '20 at 13:14
  • 1
    @V0ldek: Whoops - for the `uint`/`int` case I was thinking about arrays. (The C# compiler won't let you convert an `int[]` to `uint[]`, but the CLR is happy to do so.) It *does* still work with unboxing int vs enum though: https://gist.github.com/jskeet/bbe290432a665937be0a18841d4e1f2c – Jon Skeet Aug 16 '20 at 13:24
  • discussing particular system/.Net implemented value types misses the point entirely. It is legal to define a struct type with an implicit conversion operator. – RichardB Sep 15 '22 at 05:07

2 Answers2

5

Try this

object obj = "wer";
var isCompatible = typeof(T).IsAssignableFrom(obj.GetType());
Asif
  • 329
  • 1
  • 7
0

You can try these:

object obj = "wer";
typeof(T).IsInstanceOfType(obj)

Read more: https://learn.microsoft.com/en-us/dotnet/api/system.type.isinstanceoftype?view=netcore-3.1

Or

object obj = "wer";
obj is T;

Read more: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is

Or

object obj = "wer";
typeof(T).IsAssignableFrom(obj.GetType())

Read more: https://learn.microsoft.com/en-us/dotnet/api/system.type.isassignablefrom?view=netcore-3.1

However you need to note about the differences between IsAssignableFrom and IsInstanceOfType and is. Read more here:

https://stackoverflow.com/a/497001/1666800

https://stackoverflow.com/a/15853224/1666800

Vahid Farahmandian
  • 6,081
  • 7
  • 42
  • 62