166

If I have:

void MyMethod(Object obj) {   ...   }

How can I cast obj to what its actual type is?

Paul Lassiter
  • 2,641
  • 5
  • 22
  • 25

11 Answers11

245

If you know the actual type, then just:

SomeType typed = (SomeType)obj;
typed.MyFunction();

If you don't know the actual type, then: not really, no. You would have to instead use one of:

  • reflection
  • implementing a well-known interface
  • dynamic

For example:

// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);

// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();

// dynamic
dynamic d = obj;
d.MyFunction();
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
58

I don't think you can (not without reflection), you should provide a type to your function as well:

void MyMethod(Object obj, Type t)
{
    var convertedObject = Convert.ChangeType(obj, t);
    ...
}

UPD:

This may work for you:

void MyMethod(Object obj)
{
    if (obj is A)
    {
        A a = obj as A;
        ...
    } 
    else if (obj is B)
    {
        B b = obj as B;
        ...
    }
}
Maksim Vi.
  • 9,107
  • 12
  • 59
  • 85
  • 8
    Reflection of an object of type object will not yield the "actual type" of the object, as asked by OP. Also, your MyMethod logic is flawed because obj can be of type A and it also can be of type B. Your logic doesn't provide the "actual type" (as OP requested)--it provides a compatible type, and not necessarily the desired type at that. – Jazimov Feb 03 '18 at 01:40
  • 1
    use obj.GetType(). That will definitely return it's actual type. – JSON Mar 21 '18 at 15:04
  • We already know the 'Type'. He wants it to resolve like if it was a 'T' – Latency Sep 01 '20 at 00:52
8

How about

JsonConvert.DeserializeObject<SomeType>(object.ToString());
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
albin
  • 607
  • 6
  • 10
  • @user12637955 this is actually a working answer, but has bigger complexity, due to boxing and unboxing, i.e. object -> ToString() -> to concrete type. To be more accurate it should look like this: `var myType = JsonConvert.DeserializeObject(object.ToString());` – Coke Jun 30 '20 at 17:58
3

You could use also Pattern Matching

void MyMethod(Object obj) {   

  if(obj is SomeType myVar){
    myVar.MyFunction();
  }
}
Oscar Acevedo
  • 1,144
  • 1
  • 12
  • 19
1

If your MyFunction() method is defined only in one class (and its descendants), try

void MyMethod(Object obj) 
{
    var o = obj as MyClass;
    if (o != null)
        o.MyFunction();
}

If you have a large number in unrelated classes defining the function you want to call, you should define an interface and make your classes define that interface:

interface IMyInterface
{
    void MyFunction();
}

void MyMethod(Object obj) 
{
    var o = obj as IMyInterface;
    if (o != null)
        o.MyFunction();
}
devio
  • 36,858
  • 7
  • 80
  • 143
1

In my case AutoMapper works well.

AutoMapper can map to/from dynamic objects without any explicit configuration:

public class Foo {
    public int Bar { get; set; }
    public int Baz { get; set; }
}
dynamic foo = new MyDynamicObject();
foo.Bar = 5;
foo.Baz = 6;

Mapper.Initialize(cfg => {});

var result = Mapper.Map<Foo>(foo);
result.Bar.ShouldEqual(5);
result.Baz.ShouldEqual(6);

dynamic foo2 = Mapper.Map<MyDynamicObject>(result);
foo2.Bar.ShouldEqual(5);
foo2.Baz.ShouldEqual(6);

Similarly you can map straight from dictionaries to objects, AutoMapper will line up the keys with property names.

more info https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping

Søren
  • 6,517
  • 6
  • 43
  • 47
0

Cast it to its real type if you now the type for example it is oriented from class named abc. You can call your function in this way :

(abc)(obj)).MyFunction();

if you don't know the function it can be done in a different way. Not easy always. But you can find it in some way by it's signature. If this is your case, you should let us know.

Masoud
  • 1,354
  • 6
  • 18
  • 30
0

If multiple types are possible, the method itself does not know the type to cast, but the caller does, you might use something like this:

void TheObliviousHelperMethod<T>(object obj) {
    (T)obj.ThatClassMethodYouWantedToInvoke();
}

// Meanwhile, where the method is called:
TheObliviousHelperMethod<ActualType>(obj);

Restrictions on the type could be added using the where keyword after the parentheses.

0

Another option is to serialise it and then deserialise it as the object you want. JsonConvert.DeserializeObject<OtherType>(JsonConvert.SerializeObject(obj));

Isanderthul
  • 48
  • 1
  • 4
-2
Implement an interface to call your function in your method
interface IMyInterface
{
 void MyinterfaceMethod();
}

IMyInterface MyObj = obj as IMyInterface;
if ( MyObj != null)
{
MyMethod(IMyInterface MyObj );
}
Hassan Boutougha
  • 3,871
  • 1
  • 17
  • 17
-6

Casting to actual type is easy:

void MyMethod(Object obj) {
    ActualType actualyType = (ActualType)obj;
}
user1610694
  • 1,078
  • 7
  • 9