How to cast object to type described by Type class?
Asked Answered
A

5

29

I have a object:

ExampleClass ex = new ExampleClass();

And:

Type TargetType

I would like to cast ex to type described by TargetType like this:

Object o = (TargetType) ex;

But when I do this I get:

The type or namespace name 't' could not be found

So how to do this? Am I missing something obious here?

Update:

I would like to obtain something like this:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

private otherClass;

And because I will have many properties like this I would like do this:

public CustomClass MyClassOuter
{
   get
   {
        return (GetThisPropertyType()) otherClass;
   }
}

private SomeOtherTypeClass otherClass;

Context:

Normally in my context in my class I need to create many properties. And in every one replace casting to the type of property. It does not seem to have sense to me (in my context) because I know what return type is and I would like to write some kind of code that will do the casting for me. Maybe it's case of generics, I don't know yet.

It's like I can assure in this property that I get the right object and in right type and am 100% able to cast it to the property type.

All I need to do this so that I do not need to specify in every one property that it has to "cast value to CustomClass", I would like to do something like "cast value to the same class as this property is".

For example:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (SpecialClass) MyInteralObjects["MyVeryOwnSpecialObject"];
      }
   }
}

And ok - I can make many properties like this one above - but there is 2 problems:

1) I need to specify name of object on MyInternalObjects but it's the same like property name. This I solved with System.Reflection.MethodBase.GetCurrentMethod().Name.

2) In every property I need to cast object from MyInternalObjects to different types. In MyVeryOwnSpecialObject for example - to SpecialClass. It's always the same class as the property.

That's why I would like to do something like this:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (GetPropertyType()) MyInteralObjects[System.Reflection.MethodBase.GetCurrentMethod().Name];
      }
   }
}

And now concerns: Ok, what for? Because further in my application I will have all benefits of safe types and so on (intellisense).

Second one: but now you will lost type safety in this place? No. Because I'm very sure that I have object of my type on a list.

Aga answered 30/7, 2009 at 12:1 Comment(7)
I've updated my answer to respond to your edit. I suspect we'll need to see a complete example for this question to make sense.Twowheeler
"It's always the same class as the property" - so cast it to that type! You know that type at compile-time; why do anything else? Just to save some typing?Twowheeler
If you go out of box you will see benefits of thisAga
No, I don't see the benefit beyond making cut and paste easier. Please explain what you believe the benefits to be. Note that if you want to just generate these properties with a tool, that could very easily use the right type etc directly.Twowheeler
(I'm not talking about the benefit of having strongly-typed properties - that's fine. I'm talking about the benefit of finding the name and type dynamically when you actually know it statically anyway.)Twowheeler
@Jon Skeet - Thank you for trying to find an answer for this question.Aga
@Jon Skeet - dynamic will do the magic in .NET 4.0 : codeguru.com/vb/vbnet30/article.php/c15645__4Aga
A
1

Now it seems to be impossible, but soon will be available with new feature in .NET 4.0 called "dynamic":

http://www.codeguru.com/vb/vbnet30/article.php/c15645__4/

Aga answered 14/8, 2009 at 8:47 Comment(0)
H
11
Object o = (TargetType) ex;

This code is useless. You might have a type on the right but it's still only an object on the left side. You can't use functionality specific to TargetType like this.


This is how you can invoke a method of an unknown object of a given type:

object myObject = new UnknownType();
Type t = typeof(UnknownType); // myObject.GetType() would also work
MethodInfo sayHelloMethod = t.GetMethod("SayHello");
sayHelloMethod.Invoke(myObject, null);

With this UnknownType class:

class UnknownType
{
    public void SayHello()
    {
        Console.WriteLine("Hello world.");
    }
}
Hutchings answered 30/7, 2009 at 12:4 Comment(3)
I need to cast ex to type my custom 'TargetType'. What do you propose to get this done?Aga
You'll have to invoke methods (or whatever you want to do) via reflection. I'll try to find an example.Hutchings
Your context code still has the same problem I described. You try to cast something to (GetThisPropertyType()) but in the end you return a CustomClass instance anyway.Hutchings
T
2

Usually a desire to do this indicates a misunderstanding. However, there are very occasionally legitimate reasons to do this. It depends on whether or not it's going to be a reference conversion vs an unboxing or user-defined conversion.

If it's a reference conversion, that means the actual value (the reference) will remain entirely unchanged. All the cast does is perform a check and then copy the value. That has no real use - you can perform the check using Type.IsAssignableFrom instead, and just use the implicit cast to object if you want it in a variable of type object.

The main point of casting is to provide the compiler with more information. Now if you only know the type at execution time, that clearly can't help the compiler.

What do you plan to do with o after you've performed the cast? If you can explain that, we can try to explain how to achieve the effect you're after.

If you really want a user-defined conversion or an unboxing conversion to occur, that could be a different matter - but I suspect that's not the case.

EDIT: Having seen your update, your property is just declared to return CustomClass, so all you need is:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

I suspect you still haven't really given us all the information we need. Is that definitely how your property will be defined, with CustomClass being a definite type? Why were you trying to perform the cast dynamically when you know the property type?

EDIT: It sounds like you're just trying to save some typing - to make it easier to cut and paste. Don't. You know the type at compile-time, because you know the type of the property at compile-time (it's specified in the code just a few lines above). Use that type directly. Likewise don't try to get the name of the current method to work out the key to use. Just put the name in directly. Again, you know it at compile-time, so why be dynamic? I'm all for laziness when it makes sense, but in this case it just doesn't.

Twowheeler answered 30/7, 2009 at 12:11 Comment(7)
I may be missing the point here but it looks like he's trying to craft a generic 'get' for the properties in any class. Given that the properties isn't named I don't see how this could work but I'm happy to be educated here.Jaffna
@Lazarus: This is why I've asked for a complete example. I suspect that when we get to see more, it'll be clearer what's going on. It's possible that using generics would help, but we can't tell from the limited information we've got.Twowheeler
I need to do casting without specify the cast class direct. Inside property it's known what type it is. I would like to cast otherClass to this class type without specifying it directly because in this context it's obvious.Aga
Where do you think the benefit is in casting to any type other than the type of the property itself? If you really think you have a good reason to do this, please post a complete example.Twowheeler
@tomaszs: You can't arbitrarily cast an object to any type, it would have to be the correct type or a type from which this class inherits. I think Jon is looking to see a fully described scenario, i.e. why are you needing to do this. At the moment we are still unclear and what you are you looking to do doesn't, at least to me, make a whole lot of sense.Jaffna
@Jon Skeet - For example: I have a list of objects in my app. I would like to take some of these objects and promote them into public properties. Because I like Intellisense and other stuff I would like to make these properties more specific. If my list has objects of type BaseClass I would like have properties SpecialClass and SpecialOtherClass that will expose object of this type that is on the list. So - on the list - general type, properties - more specific. And how to do this?Aga
@Jaffna - updated question to provide complete sceniario where it's usefull for me.Aga
J
1
if (ex is ExampleClass) 
{
  ExampleClass myObject = (ExampleClass)ex;
}

That would do it but I guess the question is what are you trying to achieve and why? I often find that if something seems really, really difficult then I'm probably doing it wrong.

Jaffna answered 30/7, 2009 at 12:10 Comment(1)
Just another syntax flavor, but you can also use a switch statement like here if you have multiple class types.Yahairayahata
A
1

Now it seems to be impossible, but soon will be available with new feature in .NET 4.0 called "dynamic":

http://www.codeguru.com/vb/vbnet30/article.php/c15645__4/

Aga answered 14/8, 2009 at 8:47 Comment(0)
M
0

I'm not entirely sure what you're trying to do, but the impression I'm getting is that you'd like to have a single instance of some object which can "act like" many different types of objects, and you want to have getters which will allow you to view this one object in those various different ways very easily. In that case, I would suggest making a single getter method (not a property), like so:

public T Get<T>()
{
   return (T)myObject;
}

Then you would call it like so:

Foo foo = box.Get<Foo>();
Bar bar = box.Get<Bar>();
// etc...

Two things to note: this is definitely not type-safe, since you can pass any type for T, including types for which the cast will fail. You can constrain it a little, like so:

public T Get<T>() where T : SomeBaseType

Which will cause a compile error if you try to use a type which is incompatible with SomeBaseType, but I'm not sure that's totally robust. But hopefully this gets you most of the way there.

Is this what you had in mind?

Muraida answered 21/9, 2013 at 22:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.