0

I have a method that can return many types of objects (which is why it returns an instance of type object).

How can I cast it to its original type? (The question is about casting to its original type, when I don't know its type at run time. It is not about casting when I know its type; that's why GetAnyObject method is black box)

private void func()
{
    var obj = GetAnyObject();
    callFunc(obj);
}
private void callFunc(object o)
{
    var a = o.GetType();
    ...
}
Foon
  • 6,148
  • 11
  • 40
  • 42
Dror
  • 177
  • 3
  • 11
  • Is this language C# ? If so please mark it as such. – Ondrej Svejdar Sep 09 '15 at 12:04
  • Why do you want to cast when you are not going to have compile-time usage of casted variable. Just use reflection on the object. – Euphoric Sep 09 '15 at 12:05
  • It is really any object or can extract some methods and use an Interface? Ondrej Svejdar is right, you should use the common C# style coding ( private void CallFunc(Object o) – Bjoern Sep 09 '15 at 12:16
  • The type information is only useful at compile time; the object will have a type at runtime, but if you don’t utilize that type at compile time, you gain nothing from “casting” it (you can’t actually cast it properly). – poke Sep 09 '15 at 12:19
  • I know that my object is array, and I'll need to run through all it's elements to look for a property – Dror Sep 09 '15 at 12:27
  • I have a feeling you are violating some good principles with `GetAnyObject` that this entire problem could be avoided by refactoring into separate methods. It would help if you posted the code to *that* method, instead of the two kind-of unrelated ones you did post. – Ron Beyer Sep 09 '15 at 12:27
  • Here you will find the solution http://stackoverflow.com/questions/14320952/dynamic-cast-using-type-of-object-c-sharp – Ramankingdom Sep 09 '15 at 13:11

3 Answers3

1

You can just go ahead and cast it with as, since it will return null if the cast fails.

private void callFunc(object o)
{
    var test = a as MyClass;
    if (test != null)
    {
       // your logic
    }
}

If you have a list of classes that you need to cast to, test each of them in the body of the function above.

Candide
  • 30,469
  • 8
  • 53
  • 60
  • It's not a bad idea, but will require code modification if any new type becomes possible. – Kapol Sep 09 '15 at 12:29
  • @Dror What's your end game? Why do you want to "cast" an object? – Candide Sep 09 '15 at 14:13
  • I have some services and for each one there are some methods. – Dror Sep 10 '15 at 05:28
  • I have some services and for each one there are some methods. Sometimes I look for specific data and I want to have a application I'd be able to find it. If I had access to db I'd be able to write some queries, but I don't. Each method in a service returns array of different type of object, so this way I'd be able to "write queries" to look for the data I need – Dror Sep 10 '15 at 05:34
  • Are the queries in LINQ? Even if they are not, you have to use reflection to call the methods. `MakeGenericMethod` is one of the setup methods for invoking a method dynamically. If all (or most) classes expose a common method (either by name or by implementing an interface), you can exploit this information to find and execute that method. All, in all, it sounds like it has little to do with casting, but rather with reflection. – Candide Sep 10 '15 at 07:05
1

If the possible types have something in common, you might want to create an interface which all these types implement and cast the result to that interface type.

private void func()
{
    var obj = (IMyInterface)GetAnyObject();
    callFunc(obj);
}

private void callFunc(IMyInterface o)
{
    ...
}

In one of your comments you say that the object is an array. Maybe IEnumerable will suffice, then?

EDIT

You stated that you are using third-party code which won't be changed. Hence all the objects that you get must have something in common to make your code at least a bit generic. Otherwise you'll end up with a lot of ifs for different scenarios. One things that comes to my mind is retrieving a MemberInfo object through reflection and invoking it. That assumes all types have that member defined. I am talking about something similar to the following:

MethodInfo someMethod = obj.GetType().GetMethod("M");
object result = someMethod.Invoke(obj);

It's really hard to present a good solution without knowing the exact details of your predicament ;-)

Kapol
  • 6,383
  • 3
  • 21
  • 46
  • The problem here's that I get the data from other service written by someone else and he won't change the code for my needs (for a "nice to have application") – Dror Sep 09 '15 at 12:57
  • on the previous answer, last comment I explained what I wanted to do. The data I get from `GetAnyObject` is an array of type of object, this is the common of the data. – Dror Sep 10 '15 at 05:44
0

Casting objects to types have sense only in compile time. How you would react to the casted object in your code?

The object already has it's "original" type. The case is, when you threat it as an object you don't know its type in compile time. In runtime of course it will act as it is the "original" type you call.

Suppose you have a class, that overrides ToString() method:

public class Foo 
{
    public override string ToString() { return "I am foo"; }
}

Then you have a piece of code:

Foo foo = new Foo();
object obj = foo;
// obj is of course Foo type
Console.Write(obj.ToString());

It will of course result in writing "I am foo" to the console, because the variable obj is of type Foo, and it will act properly.

Then suppose we have a class:

public class Bar 
{
    public override string ToString() { return "I am bar"; }

    public void Foobar() {}
}

And piece of not real code that you wish to have:

object obj = new Bar();

// your runtime type casting here:
var casted = (obj.GetType()) obj;

Question is: what will you do with your casted variable? Can you call method Foobar()? How will you know if you can call method Foobar() in compile time, when you don't know the type?

Maybe the thing you seek is polymorphism? Maybe reflection? Maybe dynamic objects?

EDIT: From what you say, you need a reflection, a mechanism for investigating types in runtime. See this:

var type = obj.GetType();
var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach(var prop in props)
{
    Console.WriteLine("property: {0} type:{1}", prop.Name, prop.PropertyType);
}
Kędrzu
  • 2,385
  • 13
  • 22
  • I didn't mention, but the data I get from a service written by other person so I can't override it (all the types for "nice to have" application). The object I get is an array and I need to examine some properties of each object in this array. – Dror Sep 09 '15 at 13:06