jeudi 28 mai 2015

Using reflection to intialize native structure classes as objects

I'm punching my way through trying to familiarize myself with the reflection classes. I'm hoping to make something that will allow me to process at runtime small lines of .NET code entered into a Console and perform those actions. As such I'm creating a bunch of "wrapper" classes for anonymous objects which will allow reflection interaction with instantiated objects or preexistent objects.

My problem is when I want to "wrap" a primitive structure in one of these like "Int32," "Double," "Float." These objects have no default constructor so I'm not sure how to initialize them or if it's really even possible to initialize structures in this manner.

Here's part of my class, though this is probably not the most efficient method, I've been loading all the methodinfos/constructorinfos/fieldinfos/etc into lists and then searching through the list for the selected constructor.

Except these primitive structures have no constructors - so I don't really know how I can adapt this class to work with primitive structures or if it's even possible.

I have left out several methods, the ones that populate the lists of constructors/methods/etc, from this code. The rest is there. This is probably a horrible attempt, but I'm learning reflection as I go so I won't be surprised if I end up rewriting it all. Anyway, my problem is with the "create()" method. I was hoping I could create the structure and then use "setfield" to set the value of a native type like "Int32" but as there's no constructor, I'm not really sure how to create one of these objects in a generic manner.

public class ObjectWrapper
{
    private Type ClassType;
    private object _MyObject;
    private bool ConstLoad = false;
    private List<ConstructorWrapper> _Constructors = new List<ConstructorWrapper>();
    private bool MethLoad = false;
    private List<MethodWrapper> _Methods = new List<MethodWrapper>();
    private bool PropLoad = false;
    private List<PropertyWrapper> _Properties = new List<PropertyWrapper>();
    private bool FieldLoad = false;
    private List<FieldWrapper> _Fields = new List<FieldWrapper>();

    private bool AutoBuilt = false;

    public object Instance
    {
        get
        {
            return _MyObject;
        }
    }

    public ObjectWrapper(Type TypeToConstruct)
    {
        ClassType = TypeToConstruct;
    }

    public bool Create()
    {
        CheckCons();
        int num = -1;
        for(int i = 0; i < _Constructors.Count; i++)
        {
            if(_Constructors[i].ParamCount == 0)
            {
                num = i;
            }
        }
        if(num >= 0)
        {
            try
            {
                _MyObject = _Constructors[num].CI.Invoke(null);
                if (AutoBuilt)
                {
                    Done();
                }
                return true;
            }
            catch(Exception ex)
            {
                PO.Console.ConInt.ErrorLog("Error invoking constructor on ObjectWrapper late bind type " + ClassType.Name + "\r\nException: " + ex.Message);
                if(AutoBuilt)
                {
                    Done();
                }
                return false;
            }
        }
        else
        {
            if (AutoBuilt)
            {
                Done();
            }
            ConInt.ErrorLog("Error invoking contructor on ObjectWrapper late bind type " + ClassType.Name + ".  Error: No Constructors matching parameters");
            return false;
        }
    }

    public bool Create(object[] args)
    {
        CheckCons();
        Type[] types = new Type[args.Length];
        for(int i = 0; i < args.Length; i++)
        {
            types[i] = args[i].GetType();
        }
        int num = -1;
        for(int i = 0; i < _Constructors.Count; i++)
        {
            if(_Constructors[i].ParamCount == types.Length)
            {
                if(_Constructors[i].CheckParams(types))
                {
                    num = i;
                }                     
            }
        }
        if (num >= 0)
        {
            try
            {
                _MyObject = _Constructors[num].CI.Invoke(args);
                if (AutoBuilt)
                {
                    Done();
                }
                return true;
            }
            catch (Exception ex)
            {
                PO.Console.ConInt.ErrorLog("Error invoking constructor on ObjectWrapper late bind type " + ClassType.Name + "\r\nException: " + ex.Message);
                if (AutoBuilt)
                {
                    Done();
                }
                return false;
            }
        }
        else
        {
            if (AutoBuilt)
            {
                Done();
            }
            ConInt.ErrorLog("Error invoking contructor on ObjectWrapper late bind type " + ClassType.Name + ".  Error: No Constructors matching parameters");
            return false;
        }


    }

    #region Invokes

    public object GetField(string Name)
    {
        if(_MyObject != null)
        {
            CheckFields();

            object ret = new object();
            bool found = false;

            for (int i = 0; i < _Fields.Count; i++ )
            {
                if(_Fields[i].Name == Name)
                {
                    ret = _Fields[i].GetValue(_MyObject);
                    found = true;
                    i = _Fields.Count;
                }
            }

            if (AutoBuilt)
            {
                Done();
            }
            if (!found)
            {
                ConInt.ErrorLog("Error in retrieving field from object: " + _MyObject.GetType().FullName + ".  Field not found.");
                return null;
            }
            else
            {
                return ret;
            }
        }
        else
        {
            PO.Console.ConInt.ErrorLog("Error retrieving field, object not initialized.  Object type: " + ClassType.Name);
            return null;
        }
    }

    public void SetField(string FieldName, object value)
    {
        if (_MyObject != null)
        {
            CheckFields();

            bool found = false;

            for (int i = 0; i < _Fields.Count; i++)
            {
                if (_Fields[i].Name == FieldName)
                {
                    try
                    {
                        _Fields[i].SetValue(_MyObject, value);
                        found = true;
                    }
                    catch(Exception ex)
                    {
                        ConInt.ErrorLog("Error while attempting to set Field " + FieldName + " in object: " + _MyObject.GetType().FullName + "\r\n" + ex.Message);
                    }

                }
            }

            if (AutoBuilt)
            {
                Done();
            }
            if (!found)
            {
                ConInt.ErrorLog("Error in setting field " + FieldName + " in object: " + _MyObject.GetType().FullName + ".  Field not found.");
            }
        }
        else
        {
            PO.Console.ConInt.ErrorLog("Error setting field " + FieldName + ", object not initialized.  Object type: " + ClassType.Name);
        }
    }
}





Aucun commentaire:

Enregistrer un commentaire