Help with general questions...

I want to access a namespace and class using a string somehow.  ie instead of using:
 
ged.item.value = 5;

using instead somehow:

"ged.item.value" = 5;

I will have at run time the string representation of the location of value.  I will need to use the string to access the value.

Also,

if I have a method that uses an Object to allow access to various classes like:

public void Method(Object obj)
{
  obj.toString();
}

How do I gain access to the classes members while developing the program.  I think only the generic Object members are available

Thanks in advance,

Devin


Answer this question

Help with general questions...

  • androidi

    Super, that's what I was looking for.

    Thanks!

    Devin

  • Mary Koetting

    As far as being able to do something like:

    "ged.item.value" = 5;

    in C#, VB or most other languages you can't.  You can use dictionaries or the like to somewhat emulate this but otherwise it won't work.  As for the more general question of how to access a property or field of an object that you aren't aware of at compile time then you'll need to use reflection.  Through reflection you can access any member of an object (whether it is public or not).  In most places where you need to convert a string to an object reference  (like XAML, DataSets, or whatever) you'll need to walk the type list. 

    There are a variety of issues that you'll need to deal with including whether the property/field exists, whether it can be get or set, type conversion, whether the assembly containing the object is even loaded and how to access the initial variable.  Here is an example of a method to get and set the value of an arbitrarily nested property/field given the base object variable.  Note that it does no error checking nor does it handle arrays.

    public static object GetValue ( object baseObj, string fieldName )       
            {
                MemberInfo member = null;            //The current field/property matched           
                object data = baseObj;                //The previous object/property that matched

                string[] names = fieldName.Split('.');
                foreach (string name in names)
                {
                    //We are still going so get the current data object that we might
                    //need to set
                    if (member is PropertyInfo)
                        data = ((PropertyInfo)member).GetValue(data, null);
                    else if (member is FieldInfo)
                        data = ((FieldInfo)member).GetValue(data);

                    //Find the next property/field
                    PropertyInfo prop = data.GetType().GetProperty(name);
                    if (prop != null)
                    {
                        member = prop;
                    } else  //Not a property so try the fields
                    {
                        FieldInfo field = data.GetType().GetField(name);
                        if (field != null)
                        {
                            member = field;                       
                        };
                    };
                };

                //Have walked the entire string so we can get the value of the current object
                if (member is PropertyInfo)
                {
                    return ((PropertyInfo)member).GetValue(data, null);
                } else
                {
                    return ((FieldInfo)member).GetValue(data);
                };
            }

            public static void SetValue ( object baseObj, string fieldName, object value )
            {
                MemberInfo member = null;            //The current field/property matched
                Type typeCurr = baseObj.GetType();    //The current type of the field/property matched
                object data = baseObj;                //The previous object/property that matched

                string[] names = fieldName.Split('.');
                foreach (string name in names)
                {
                    //We are still going so get the current data object that we might
                    //need to set
                    if (member is PropertyInfo)
                        data = ((PropertyInfo)member).GetValue(data, null);
                    else if (member is FieldInfo)
                        data = ((FieldInfo)member).GetValue(data);
                   
                    //Find the next property/field
                    PropertyInfo prop = typeCurr.GetProperty(name);
                    if (prop != null)
                    {
                        typeCurr = prop.PropertyType;
                        member = prop;                   
                    } else  //Not a property so try the fields
                    {                   
                        FieldInfo field = typeCurr.GetField(name);
                        if (field != null)
                        {
                            typeCurr = field.FieldType;
                            member = field;               
                        };
                    };               
                };

                //Have walked the entire string so we can set the value of the current object
                if (member is PropertyInfo)
                {
                    ((PropertyInfo)member).SetValue(data, value, null);
                } else
                {
                    ((FieldInfo)member).SetValue(data, value);
                };
            }

    As for your second question if you are sure of the underlying type of the object then a simple cast will work like so:

    public void Method ( object obj )
    {
       MyType typedObj = obj as MyType;
     
       typedObj....
    }

    If the as operator fails then the object was not of the appropriate type or it was null.  To do this on a general basis you again would have to use reflection.  Interfaces are actually good for this kind of scenario as well.


  • Help with general questions...