Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cast object to its actual type

Tags:

c#

.net

upcasting

Consider the following piece of code:

class MyClass
{
}

class MyClass2 : MyClass
{
}

private void Foo(MyClass cl)
{
    //cl is actually MyClass2 instance
    TestGeneric(cl);
}

private void TestGeneric<T>(T val)
{
     //do smth
}

After calling Foo(), the T in TestGeneric is MyClass, not MyClass2. How do I achieve treating val as a MyClass2 instance? Thanks in advance.

Upd: I don't actually know that the object has been created using MyClass2 ctor, but rather can infer this by calling val.GetType() so a simple as MyClass2 won't work

like image 750
Gena Verdel Avatar asked Nov 29 '12 08:11

Gena Verdel


People also ask

How do you cast an object to a specific class?

Class class is used to cast the specified object to the object of this class. The method returns the object after casting in the form of an object. Return Value: This method returns the specified object after casting in the form of an object.

Is used to convert an object or variable of one type into another?

You convert an Object variable to another data type by using a conversion keyword such as CType Function.


2 Answers

It can be done with a visitor pattern. It is a nice object oriented approach, when you have all handling code in a single handler class (not in each message) and if more message types will be needed, just add additional handler methods.

// Your message classes
public class MyClass : IMessage
{
    // Implement acceptance of handler:
    public void AcceptHandler(IMessageHandler handler)
    {
        handler.HandleMessage(this);
    }
}

public class MyClass2 : MyClass
{
     // Nothing more here
}

// Define interface of message
public interface IMessage
{
    void AcceptHandler(IMessageHandler handler)
}

// Define interface of handler
public interface IMessageHandler
{
    // For each type of message, define separate method
    void HandleMessage(MyClass message)
    void HandleMessage(MyClass2 message)
}

// Implemente actual handler implementation
public class MessageHandler : IMessageHandler 
{
    // Main handler method
    public void HandleSomeMessage(MyClass message) // Or it could be IMessage
    {
         // Pass this handler to message. Since message implements AcceptHandler
         // as just passing itself to handler, correct method of handler for MyClass
         // or MyClass2 will be called at runtime.
         message.AcceptHandler(this);
    }

    public void HandleMessage(MyClass message)
    {
         // Implement what do you need to be done for MyClass
    }

    public void HandleMessage(MyClass2 message)
    {
         // Implement what do you need to be done for MyClass2
         // If code of MyClass should be run too, just call 
         // this.HandleMessage((MyClass)message);
    }
}
like image 113
Algirdas Avatar answered Sep 23 '22 22:09

Algirdas


Assuming you can change Foo, but not its signature, you could do this:

private void Foo(MyClass cl)
{
    TestGeneric((dynamic)cl);
}

This will resolve the version of TestGeneric that gets called at runtime instead of at compile time, calling TestGeneric<MyClass2> when cl is of that type.

like image 25
Matthew Strawbridge Avatar answered Sep 21 '22 22:09

Matthew Strawbridge