Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by lastprogrammer · Dec 20, 2013 at 02:29 PM · casting

Dynamic Casting during runtime

So here is a simple problem but I don't know the answer to. I have looked and everyone has said that dynamic casting is impossible but I will give you good people a try.

string aStringVar; object anObjVar;

aStringVar = anObjVar;//this gives a compiler error

Can I change that last line to this:

aStringVar = (aStringVar.GetType())anObjVar;//still gives me a compiler error!

Is there a way that I can make that cast a dynamic type?

aStringVar = (string)anObjVar;//this will compile, but this isn't what I want

Thanks for your help and your understanding.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Dec 20, 2013 at 02:33 PM 0
Share

You can do it with a generic function I guess - I don't really understand what you are getting at though - do you want to just convert things from one type to another? But you don't know the type in advance?

If that's the case (and it's the only one I can think of) then you need to write a generic method that takes any type (or any type of a certain class etc).

http://msdn.microsoft.com/en-us/library/twcad0zb.aspx

avatar image lastprogrammer · Dec 20, 2013 at 03:39 PM 0
Share

There isn't anyway to cast something dynamically is the answer that I have discovered. Ins$$anonymous$$d I am using Reflection to solve the problem.

Reflection uses objects as parameters, so all I have to do is use PropertyInfo.SetValue(object obj), and that works fine.

avatar image whydoidoit · Dec 20, 2013 at 05:22 PM 0
Share

Well not in the version in Unity - you'd need a dynamic to do that in .NET - don't believe that it is supported yet.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by whydoidoit · Dec 20, 2013 at 05:33 PM

This is my ReflectionWrapper which you can construct on an instance of an object, a type etc and will let you call public and private methods. I use it mostly to wrap things that aren't supposed to be exposed by Unity.

It can do things like setting/getting a sub property whatever. It's got generics to cast the type more easily:

 var wrapper = new ReflectionWrapper(someObject);
 int i = wrapper.GetValue<int>("somePropertyOrField");
 string j = wrapper.GetValue<string>("someObjectFieldOrProperty.someStringProperty");
 wrapper.SetValue("someOtherObjectFieldOrProperty.someString", j);
 wrapper.Call("SomeMethod");
 int = wrapper.Call<int>("SomeFunction");

You can also wrap an object by just knowing its type name and assembly then call ConstructInstance:

 using UnityEngine;
 using UnityEditor;
 using UnityEditorInternal;
 using System.Collections;
 using System;
 using System.Reflection;
 using System.Linq;
 
 public class ReflectionWrapper
 {
     public Type baseType;
     public object instance;
 
     public ReflectionWrapper(string assemblyName, string typeName)
     {
         var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a=> { return a.GetName().Name == assemblyName; });
         baseType = assembly.GetType (assemblyName + "." + typeName);
         if(baseType == null)
             baseType = assembly.GetType (typeName);
     }//
 
     public ReflectionWrapper(Assembly assembly, string typeName)
     {
         baseType = assembly.GetType (typeName);
     }
 
     public ReflectionWrapper(object instance)
     {
         baseType = instance.GetType();
         this.instance = instance;
     }    
 
     public object this[string path]
     {
         get
         {
             return GetValue(path);
         }
         set 
         {
             SetValue (path, value);
         }
 
     }
 
     public object GetValue (string path)
     {
         var pathParts = path.Split('.');
         var currentObject = instance;//
         for(var i = 0; i < pathParts.Length; i++)
         {
             var f = currentObject.GetType().GetField(pathParts[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
             if(f != null)
             {
                 currentObject = f.GetValue(currentObject);
             }
             else
             {
                 var p = currentObject.GetType().GetProperty(pathParts[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                 if(p == null)
                     throw new Exception("Property not found: " + pathParts[i]);
                 currentObject = p.GetValue(currentObject, null);
             }
 
         }
         return currentObject;
     }
 
     public void SetValue (string path, object value)
     {
         var pathParts = path.Split('.');
         var currentObject = instance;//
         for(var i = 0; i < pathParts.Length-1; i++)
         {
             var f = currentObject.GetType().GetField(pathParts[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
             if(f != null)
             {
                 currentObject = f.GetValue(currentObject);
             }
             else
             {
                 var p = currentObject.GetType().GetProperty(pathParts[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                 if(p == null)
                     throw new Exception("Property not found: " + pathParts[i]);
                 currentObject = p.GetValue(currentObject, null);
             }
             
         }
         //Set the last part
         {
             var f = currentObject.GetType().GetField(pathParts[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
             if(f != null)
             {
                 f.SetValue(currentObject, value);
             }
             else
             {
                 var p = currentObject.GetType().GetProperty(pathParts[i], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                 if(p == null)
                     throw new Exception("Property not found: " + pathParts[i]);
                 p.SetValue (currentObject, value, null);
             }
         }
     }
 
     public T GetValue<T>(string path)
     {
         return (T)GetValue (path);
     }
 
     protected void ConstructInstance(Type [] types, params object[] parameters)
     {
         var constructor = baseType.GetConstructor (types);
         instance = constructor.Invoke (parameters);
     }
 
     protected void ConstructInstance(params object[] parameters)
     {
         var constructor = baseType.GetConstructor (parameters.Select (p => p.GetType ()).ToArray ());
         instance = constructor.Invoke (parameters);
     }
 
     public T GetProperty<T>(string name)
     {
         return (T)GetProperty (name);
     }
 
     public T GetField<T>(string name)
     {
         return (T)GetField (name);
     }
 
     public T Call<T>(string name, params object[] parameters)
     {
         return (T)Call (name, parameters) ;
     }
 
     public object GetProperty(string name)
     {
         return baseType.GetProperty (name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).GetValue (instance, null);
     }
     public void SetProperty(string name, object value)
     {
         baseType.GetProperty (name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue (instance, value, null);
     }
     public object GetField(string name)
     {
         return baseType.GetField (name, BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance).GetValue (instance);
     }
     public void SetField(string name, object value)
     {
         baseType.GetField (name, BindingFlags.Public | BindingFlags.NonPublic| BindingFlags.Instance).SetValue (instance, value);
     }
     public object Call(string name, params object[] parameters)
     {
         var method = baseType.GetMethods (
             BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
             .FirstOrDefault (m => {
 
                 if(m.Name != name) return false;
                 var parms = m.GetParameters();//
                 for(var i = 0; i < parms.Length; i++)
                 {
                     if(i >= parameters.Length && !parms[i].IsOptional)
                         return false;
                     if(i < parameters.Length && !parms[i].ParameterType.IsAssignableFrom(parameters[i].GetType()))
                        return false;
                 }
 
                 return true;
             });
         return method.Invoke (instance, parameters    );
     }
     public object CallStatic(string name, params object[] parameters)
     {
         var method = baseType.GetMethods (
             BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
             .FirstOrDefault (m => {
                 
                 if(m.Name != name) return false;
                 var parms = m.GetParameters();//
                 for(var i = 0; i < parms.Length; i++)
                 {
                     if(i >= parameters.Length && !parms[i].IsOptional)
                         return false;
                     if(i < parameters.Length && !parms[i].ParameterType.IsAssignableFrom(parameters[i].GetType()))
                         return false;
                 }
                 
                 return true;
             });
         return method.Invoke (null, parameters    );
     }
 
     public void SetDelegate(string name, Delegate del)
     {
 
         var field = baseType.GetField (
             name,
             BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
         if (field != null)
         {
             field.SetValue (instance, Delegate.CreateDelegate (field.FieldType, del.Target, del.Method));
         }
         else
         {
             var property = baseType.GetProperty(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
             property.SetValue (instance, Delegate.CreateDelegate (property.PropertyType, del.Target, del.Method), null);
         }
     }
 
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · Dec 20, 2013 at 05:35 PM 0
Share

Oh yeah and as a shortcut you can do:

    wrapper["Something.SomethingElse"] = 1;
    object o = wrapper["SomeProperty"];
avatar image whydoidoit · Dec 20, 2013 at 05:40 PM 0
Share

BTW the reason ConstructInstance is protected is that in the case that you are making these things I sub class RefectionWrapper to make a nice interface to it and to encapsulate the necessary constructor parameters.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

19 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Problem with type casting from C# to JS 3 Answers

Cannot cast from source type to destination type 0 Answers

How do I cast an IntPtr to another class? 0 Answers

Converting to ColliderCast - what's included in the PhysicsWorld and how do I include my own meshes? 0 Answers

Error, class project 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges