locked
Dynamic Casting in C# at runtime

    Question

  • How Can I dynamically cast at runtime.That is I am passing a child class object in the parent class object in a function.In that function i have to cast to passed child class object at runtime.

    How Can I Cast It.

     

    protected void Page_Load(object sender, EventArgs e)

    {

    Circle circleObj = new Circle();

    circleObj.Radius = 5;

    Response.Write(chkRefrence(circleObj)+"<br \\>After ");

    }

    private string chkRefrence(Shape shapeObject)

    {

    //Type t = shapeObject.GetType();

    ((t) shapeObject).Radius = 15;  //It is here I want's to cast to Circle

    shapeObject.Id = "TestObj ";

    return shapeObject.ToString();

    }

    Tuesday, May 02, 2006 11:51 AM

Answers

  • A solution for this would be the use of a generic method that is invoked by reflection. To cast the object obj to type t:

            public static T Cast<T>(object o)
            {
                return (T)o;
            }

    Then invoke this using reflection:

            MethodInfo castMethod = this.GetType().GetMethod("Cast").MakeGenericMethod(t);
            object castedObject = castMethod.Invoke(null, new object[] { obj });

    Sunday, February 25, 2007 12:23 PM

All replies

  • If you know there is a Radius property to set, you must also know that the type is Circle (or something else that has a Radius property - define an interface for it if there are other possible types). So just cast to that.

     

    Tuesday, May 02, 2006 12:32 PM
  • It is just a example .

    I want's to ask about dynamic casting

    i.e.

    ((t) shapeObject).Radius = 15;  //It is here I want's to cast to Circle or what ever my class

    Please if any body can answer to the point then help me

    Tuesday, May 02, 2006 12:34 PM
  •  Kamii47 wrote:

    It is just a example .

    How about providing a realistic example then, one which shows what you're actually trying to accomplish. There's no such thing as "dynamic casting". Your options are basically

    - Declare the members you want to use in a base class or interface and cast to that.

    - Use generics.

    - Use Reflection.

     

    • Unmarked as answer by Kamran Shahid Friday, April 08, 2011 12:10 PM
    Tuesday, May 02, 2006 1:53 PM
  • Hi,
    it depends on what you want to cast and to what type. If you have a shapeObject and you want to cast it safely to a circle then first check if the object is indeed a circle. Don't know if I understand you correctly but check the example:

    Circle c = shapeObject as Circle;
    if(c != null)
        c.Radius = 15;

    // or

    if(shapeObject is Circle)
        ((Circle)c).Radius = 15;

    Tuesday, May 02, 2006 3:45 PM
  • I don't know which class to be cast at rutime.certtainly it will be a child class.
    Wednesday, May 03, 2006 4:28 AM
  • Read Mattias Sjögren's post then
    Wednesday, May 03, 2006 5:20 AM
  • The problem is that you really don't know what you want to do.  For example, your chkRefrence method won't work.  I mean, even if it were to compile, it would do what you wanted it to do.  For example, consider what would happen if you called it with a Square object.  The important line would be:
    ((Square) shapeObject).Radius = 15;

    But Squares don't have a Radius property.

    n0n4m3's example is what you really want.
    Friday, July 14, 2006 1:42 PM
  • I have done it using generic and it were a very old issue.
    Friday, July 14, 2006 2:00 PM
  • Hi,

     A big thank you to MladenP, coz he has displayed the link to the site on which i got the following code,

    string sType = "System.Int32";
    object o1 = "123";
    object o2 = Convert.ChangeType(o1, Type.GetType(sType));
    Type t = o2.GetType(); // this returns Int32 Type

    So i guess u can dynamically cast at run-time!

    Cheers,

    Senaka.

    • Proposed as answer by jfranta Thursday, April 23, 2009 11:15 PM
    Wednesday, September 06, 2006 4:14 AM
  • That's conversion, not casting. Since the type of o2 is object, you still can't access any members that are specific to the type you convert to without casting or using reflection.

     

    Wednesday, September 06, 2006 8:46 AM
  • I know this is an old thread, but I am having the exact same problem and I can give a very concrete example.

    I am writing a utility that dynamically creates a proxy class from a WSDL and then calls web methods on an instance of the proxy class.  I have no idea what types exist in the class, but I need to create instances of them complete with all their properties (which may be custom classes themselves).  So I am looping through the fields in the method's parameters using reflection and I have user supplied values that I need to insert into the parameters' fields. 

    Here's what I know at runtime:

    1. The Object (representing the parameter) that I need to insert the value into.

    2. The Type of the parameter field (from the FieldInfo class).

    3. The value (as a string) that I need to insert into the parameter field.

     

    Here's what I know at design time:

    1. Jack squat.  The parameter field could be any value type or a custom enum declared in the proxy class.

     

    The Convert.ChangeType() thing works great for value types, but blows it on Enums.  So the question stands:

    Is there a way to dynamically cast an object if you know the type at runtime?  Here is the line of code I need to make work (assume the o = the Object, t = the Type, fi = the FieldInfo, value = the String value)

    fi.SetValue(o, value)

    The Type of the string value needs to match the Type of the field in the Object o.

     

     

    Thursday, January 25, 2007 9:34 PM
  • Youre problem again has nothing to do with dynamic casting (it really doesn't exist, not in concept, not in any language). Youre problem has to do with how to use reflection. Use reflection on the Enums type to get the possible values. It's found in the field types of the enumeration.
    Friday, January 26, 2007 3:02 PM
  • But the problem isn't how to get the possible values of the enum, that's easy.  It isn't even telling which or those values equates to the value string (again easy).  The problem is how to set the value of an enumeration object that you don't know the type of at design time.  I'm starting with an object which has a property which is an Enum of an unknown Type (unkown at deisgn time), and a string which represents the value to go into it.  I need to end up with an object of a specified Type (known only at runtime) with the values of its properties set. 

    As I've said, a conversion between types exists for primitive types: Convert.ChangeType.  So we can quibble over whether or not that is truly "dynamic casting", but that is academic.  It is changing the Type of an object at runtime and "dynamic casting" seems like a good way to describe that to me.  The bottom line is that I'm looking for something which works like Convert.ChangeType, but for Enums.

    Friday, January 26, 2007 4:29 PM
  • Something micvos said got me thinking.  So I can't seem to cast the object as the specific Enum type that I need, but in a way he is right in his last post.  I can get to all of the field members of the Enum type using reflection, so I am finding the "value__" field which holds the integer value of the enum and using that to set the value like this:

    //Set up the values in a way that is usable

    int enumValue = [assume that I have already discovered which integer value equates to the string I had];

    object[] enumValueArray = new object[]{enumValue};

    //Then create an instance (I'm using some custom code that I already have, but any way of creating an instance such as Activator.CreateInstance should work)

    object enumInstance = dynamicWebServiceProxy.CreateObject(f.FieldType.Name);

    //Now invoke the member with the SetField binding flag.  No need for a custom Binder object (leave it null)

    f.FieldType.InvokeMember("value__", BindingFlags.SetField, null, enumInstance, enumValueArray);

    This code works, I end up with an enum object with its value set to the value I needed.  I suspect the answer for anyone else trying to do "dynamic casting" is going to be some combination of reflection and generics (reflection and Convert.ChangeType() in my case) like everyone keeps saying on every message board where this comes up.

    Friday, January 26, 2007 5:16 PM
  • I have a similar issue in that I know I'm receiving an enumeration, but what type of enumeration I do not know.  I need to get the integral value of the enumeration to put into a SQL statement.  The issue is that I knew the enumeration had to be an integral type other than char, but that meant signed and unsigned.  Also, since my value is of type object (as it could hold anything at any given time, so generics were not a solution here) the integral type had to be unboxed.  However, unless it is cast to the specific type, an exception is raised.  For example, you would think that you should be able to unbox a short into a long, but that doesn't work.  A short has to be unboxed into a short.  Anyway, since I'm just feeding the integral value into a string, I wasn't too concerned that the results of my conversion ended back up in an object.  I know this isn't specifically an answer to anybody's issue posted here, but I hope it will help anyone else who ends up at this post the same way I did.  Here is the code I used:

    Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()))

     

    Thursday, February 08, 2007 6:57 PM
  • A solution for this would be the use of a generic method that is invoked by reflection. To cast the object obj to type t:

            public static T Cast<T>(object o)
            {
                return (T)o;
            }

    Then invoke this using reflection:

            MethodInfo castMethod = this.GetType().GetMethod("Cast").MakeGenericMethod(t);
            object castedObject = castMethod.Invoke(null, new object[] { obj });

    Sunday, February 25, 2007 12:23 PM
  • Dewd thanks so much for this.Made my time of searching sooooooo much less
    Tuesday, May 22, 2007 9:41 AM
  • I've had, I guess, the same problem. I think the guys up there didn't get it what you really wanted.

     

    As far as I know, there is no way on the framework for you to do a dynamic cast. But I could find a workaround, I wanted to create component-like class libraries (with or without GUI); I know there will be a new namespace called AddIns on VS2008 which allows you to load namespaces dynamically, but I don't if it will work the way I want and if it will be stable.

     

    The point is, I managed to get the result I wanted using Interfaces. I created a Interface for the class I wanted to be casted, I made the class to support that Interface. Then I loaded the Interface by reffering it on the target project, the one I would like to use the class I created. The catch is that I loaded my class dynamically, so the type would never be avaliable, in runtime, to the target project to perform the cast. The class was loaded using AppDom and reflection so I didn't know to which class I should cast to since that class was unknown to my project at runtime (and that's how I wanted to be, any new feature I add will be, by definition, a new feature. My system has to know how to load it and handle it - it should behave like a dynamic component). The deal is CAST TO THE INTERFACE AND YOU CAN ACCESS THE OBJECT USING INDIRECTION.

     

    Hope I helped some way. For my worked so far.

     

    Best regards

     

    M Bitran   

    Wednesday, September 19, 2007 7:56 AM
  •  

     

    -----------------------------------------------------------------

     

     

    private void button1_Click(object sender, EventArgs e)

    {

     

    sobrecargasdin sd = new sobrecargasdin();

    exect(sd, "metodo", new object[] { new uno() } , false);

     

     

    }

     

    private void exect(object objeto, string metodo, object[] arguments,bool reflection )

    {

    object result=null;

    if (reflection)

    {

    result = objeto.GetType().InvokeMember(metodo, BindingFlags.InvokeMethod, null, objeto, arguments);

    }

    else

    {

    ((sobrecargasdin)objeto).metodo((uno)arguments[0]);

    //necesito cambiar el casting por cada tipo mandado a object que no se que es , reflextion lo resuelve automaticamente

    // y ademas un swicht para reconocer el metodo por parametro y ejecutar ese

    }

    textBox1.Text += " " + ((result != null) ? result.ToString() : "null");

    }

     

     

     

    ----------------------------------------------------------------

    class sobrecargasdin

    {

    public string metodoejecutado;

     

    public void metodo(uno u)

    {

    this.metodoejecutado = u.ToString();

    }

    public void metodo(dos d)

    {

    this.metodoejecutado = d.ToString();

    }

    public void metodo(tres t)

    {

    this.metodoejecutado = t.ToString();

    }

     

     

     

    }

     

    -------------------------------------

     

     

     

    class uno

    {

    }

     

    class dos

    {

    }

     

    class tres

    {

    }

     

    ------------------------------------

     

    // emiliano almasia 

    //emialmasia@gmail.com

    Saturday, September 22, 2007 6:15 PM
  • Hi,

    Here's a very concrete example of what I want to do:

        public class DataAccessHelper  
        {  
            public static T GetValueFromReader<T>(IDataReader reader, string collumnName)  
            {  
                int ordinal = reader.GetOrdinal(collumnName);  
                T rez;  
                if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition().FullName == typeof(int?).GetGenericTypeDefinition().FullName)  
                {  
                    //if type is nullable  
                    rez = reader.IsDBNull(ordinal) ? new T() : new T((typeof(T).GetGenericArguments()[0])reader.GetValue(ordinal));  
                }  
                else 
                {  
                    rez = (T)reader.GetValue(ordinal);  
                }  
                return rez;  
            }  
        } 

    I want this method to work when I call:
    GetValueFromReader<int>(...)
    GetValueFromReader<int?>(...)
    GetValueFromReader<string>(...)

    Is there any way to do this?
    Monday, June 30, 2008 9:49 AM
  • I may be missing exactly what you are trying to do, but would this serve your purpose?

       public class DataAccessHelper     
        {     
            public static T GetValueFromReader<T>(IDataReader reader, string collumnName)     
            {     
                int ordinal = reader.GetOrdinal(collumnName);     
                T rez;     
                iftypeof(T) == reader.GetFieldType(ordinal) )  
                {  
                    iftypeof(T).IsValueType )  
                        rez = reader.GetValue(ordinal);  
                    else 
                    {  
                        rez = reader.IsDBNull(ordinal) ? new T() : new T(reader.GetValue(ordinal));     
                    }  
                }  
                return rez;  
            }     
        }    
     
    Monday, June 30, 2008 5:47 PM
  • See www.codeplex.com/stdextlib. In the System.Extensions.dll assembly find System.Extensions.ObjectExtensions.ChangeType and System.Extensions.ObjectExtensions.ChangeTypeAny methods. Now you can write:

    var result = obj.ChangeTypeAny(typeof(string)); 

    E' più facile spezzare un atomo che un pregiudizio
    Thursday, October 16, 2008 3:50 AM
  • Thanks Christoph. You have saved me my sanity! Just what I was looking for, and I have been looking for some time.
    Thursday, January 29, 2009 6:46 PM
  • Hi Kamran,

    Why you are not making the setters Radius and Id in the base class Shape to be virtual and in the deried to override them.
    Also to override ToString function, because in Object class is virutual and you will even do not have a need to make dynamical cast,
    because in virutual table the function of the instance will be called.

    Nice day,
    Elitsa
    Wednesday, May 20, 2009 3:11 PM
  • My dear elitsa it is just an example.
    As mentione in my last post i have already done it via generics.I follow about the same approach which was later identified by Christoph.
    Thanks
    Kamran Shahid Senior Software Engineer/Analyst (MCP,MCAD,MCSD.NET,MCTS,MCPD.net[web])
    • Proposed as answer by Saeed Amiri Tuesday, September 22, 2009 7:04 AM
    Monday, August 31, 2009 8:44 AM
  • See http://codegoeshere.blogspot.com/2007/05/dynamic-cast-in-c.html after that run your methods with InvokeMember
    Tuesday, September 22, 2009 7:14 AM
  • yes BUT after invoke castedObject is just object 

    how do you use it as  Circle?
    may be invoke it as var?

    Sunday, January 24, 2010 9:21 AM
  • qprayback, replying to very old post but I am working ona project very similar to what you might have worked before. I am also reading the methods, properties and parameters of a WCF service contract. And then execute the method by using user supplied values (strings). Challenge is to how to cast the string to different types that user can define in his class methods - enum, Color, XMLExlement, Circle to name a few. You explained how you did it for enum. But the solution seems to be specific not generic. Do you have any generic solution that can be applied to all types? Or you used switch case for each type?
    Thursday, January 20, 2011 4:12 PM
  • Guess what, that doesn't work, for the same reason (double)(object)(int)5 doesn't work.
    Friday, July 08, 2011 2:38 AM
  • Christoph found the way, but still his code will not work for value types, for example for casting a double to int. Reflection allows making the type dynamic, but the variable to be cast, if it's a value type, has to be boxed into an object. And evaluating (int)(object)3.9 throws an InvalidCastException, even though (int)3.9 (without boxing) is perfectly valid. You would need to unbox the double then cast into int, even though both operations use the same syntax, they're different.

    All this is because C# and the .NET are after all in principle statically typed. It may be possible to work around it with additional reflection, but there's a simpler way. Since version 4 C# was extended with the dynamic keyword, so that dynamic typing (not just statically typed polymorphism and boxing) is actually allowed. So with a minor modification:

    public static class Extensions
    {
        private static T Cast<T>(dynamic o)
        { return (T)o; }
        
        /// <exception cref="System.InvalidCastException"></exception>
        public static dynamic DynamicCast(this Type T, dynamic o)
        {
            return typeof(Extensions).GetMethod("Cast", BindingFlags.Static | BindingFlags.NonPublic)
                .MakeGenericMethod(T).Invoke(null, new object[] { o });
        }
    }

    Now the following call would work as intended, without throwing an exception (as it would happen if we used object instead of dynamic for the parameters):

    double x1 = 3.9;
    Type t2 = typeof(int);
    var x2 = t2.DynamicCast(x1);
    Console.WriteLine("{0} {1} as {2} is {3}",
        x1.GetType(), x1, x2.GetType(), x2);


    • Edited by Javier AP Monday, October 10, 2011 1:51 PM
    Monday, October 10, 2011 9:24 AM
  • Perhaps I'm missing something, but how does this help given that the return type of Invoke is always Object? You then have to figure out how to cast the returned Object to the desired type, so you're back with the original problem.

    Wednesday, November 02, 2011 3:52 PM
  • If you tried my code, you'd find it does work. :) As for the explanation for this behavior, you can refer to point 4.7 of the C# specification, v4.0:

    "There is an implicit identity conversion between object and dynamic."

    Not that I have found this dynamic casting thing useful yet, thogh...

    Thursday, November 03, 2011 1:13 PM
  • If you want convert object dynamically you can use the function

    Convert.ChangeType(object obj, Type t);

    Monday, February 20, 2012 8:28 PM
  • That has already been proposed 5½ years ago. It's not a solution to the problem, since it returns an Object that you still need to cast to the type you want.

    Tuesday, February 21, 2012 1:46 PM
  • This is not dynamic. As you have to pass the type while calling the function. It would dynamic if you can type name as string at runtime and function will return the corresponding object.

    Dynamic casting is like asking blind person what is the shape of the object in front you.

    Tuesday, April 24, 2012 3:54 PM
  • Dynamic means resolved at run-time, so some of this can be considered dynamic; reflection is dynamic.

    Nevertheless this looks purely theoretical to tme, the example originally posted by Kamram was in my opinion a very bad solution for his problem, even if C# were dynamically typed, which it isn't.

    Wednesday, April 25, 2012 3:14 PM
  • This is not dynamic. As you have to pass the type while calling the function. It would dynamic if you can type name as string at runtime and function will return the corresponding object.

    Dynamic casting is like asking blind person what is the shape of the object in front you.

    The question is 6 years old and has already been answered.  If you would like to help and contribute to these forums by answering questions it is best to respond to unanswered questions asked within the past few days.

    Additionally, it is usually not appropriate to mark your own posts as an answer.  If you didn't feel it was an answer you wouldn't have posted it, so obviously you feel it should be the answer.  Proposing a post as the answer is a way for other readers to agree without spamming the thread.

    Wednesday, April 25, 2012 3:26 PM
  • Hi I understood your problem.

    Suppose we are having a List<DynamicClass.Class1> that is created at runtime

    and we are getting DynamicClass.Class1 object using reflection like this

     Type typeofList = typeof(System.Collections.Generic.List<>);
     Type[] arrType = typeofList.GetGenericArguments();

     Type typofClass = Type.GetType(ClassType);//Classtype is a string something like "Namespace.Class" and this is the class that our list accepts

     Type changedTypeOfListClass = typeofList.MakeGenericType(new Type[] { typofClass });
     dynamic objOfList = Activator.CreateInstance(changedTypeOfListClass); // So here creating a List<NameSpace.Class>

    object InfoClassObject = Activator.CreateInstance(typofClass );//trying to create an object of NameSpace.Class using Type

    objOfList.Add(InfoClassobject); //trying to add NameSpace.class to List

    But last line throws an exception because List accepts NameSpace.Class but we are passing an object.

    So we are suppsoed to typecast object to NameSpace.Class.

    This is the problem that you described above.

    My solution is 

    dynamic InfoClassObject = Activator.CreateInstance(typofClass );

    instead of

    object InfoClassObject = Activator.CreateInstance(typofClass );

    dynamic will take care of everything. I mean runtime typecasing and when we add InfoClassObject to list it will not throw any exception.

    Thanks,

    pavan

    Please Visit my site: pavanarya.wordpress.com

    Tuesday, July 17, 2012 9:47 AM