Friday, October 30, 2009

Set a Property Value to Null given a tree of objects and the path

 

This code was developed by Snippet Compiler (once again).

These code could be used in other things. The original prupose was to set some properties to null, from a given path to the property as a string.

 

using System;
using System.Collections.Generic;
using System.Reflection;

public class Type1
{
    string _Value1 = "Value1";
    public string Value1
    {       
        get { return _Value1; }
        set {_Value1 = value; }
    }
    public string Dummy
    {
        get {return "dummy";}
    }
}

public class Type2
{
    protected string _Value2;
    public Type2(string v)
    {
        this._Value2 = v;
    }
    public string Value2
    {
        get { return _Value2; }
        set {  Console.WriteLine("someone is setting me to" + (value??"null"));  _Value2 = value; }
    }

}

public class Type3
{
    Type2[] v = new Type2[2]{ new Type2("Value221"), new Type2("Value222")  };
    public Type1 Value11
    {  get { return new Type1(); }}
    public Type2[] Value22
    {  get { return v; } set {v=value;} }
    public void PrintMe()
    {       
        object obj1 = this.GetType().InvokeMember("Value11", BindingFlags.GetProperty, null, this, new Object[0]);       
        System.Console.WriteLine(obj1.ToString());       
        object obj2 = this.GetType().InvokeMember("Value22", BindingFlags.GetProperty, null, this, new Object[0]);
        object[] objArray2 = (object[])obj2;
        foreach(object currentObj in objArray2)
        {
            System.Console.WriteLine(currentObj);
        }
    }
}

public class MyClass
{

    public static object SetPropertyToNull(object obj, string propertyName, string propertyValues, bool setFatherToNull)
        {
            if (obj == null)
            {
                return null;
            }
            int firstDotPropertyName = propertyName.IndexOf(".");
            string childPropertyName = String.Empty;
            string remainingPropertyName = String.Empty;

            //Get the property name no eval and the remaining string of the property name
            if (firstDotPropertyName < 0)
            {
                firstDotPropertyName = 0;
                childPropertyName = propertyName;
                remainingPropertyName = String.Empty;
            }
            else
            {
                int remainningPropertyLength = (propertyName.Length - firstDotPropertyName - 1);
                remainingPropertyName = propertyName.Substring(firstDotPropertyName + 1, remainningPropertyLength);
                childPropertyName = propertyName.Substring(0, firstDotPropertyName);
            }

            //Get the type
            Type initType = obj.GetType();
            //Get the child object
            object objChild = initType.InvokeMember(childPropertyName,
                BindingFlags.GetProperty, null, obj, new object[0]);

            //As default the object will not be changed
            object returnedObj = objChild;

            if (String.IsNullOrEmpty(remainingPropertyName))
            {
                //If the element is the rigth one, set it to null
                if (String.IsNullOrEmpty(propertyValues) || (propertyValues.IndexOf(String.Format(".{0}.", objChild))) >= 0)
                {
                    initType.InvokeMember(childPropertyName,
                        BindingFlags.SetProperty, null, obj, new Object[] { null });
                    if (setFatherToNull)
                    {
                        obj = null;
                    }
                }
            }
            else
            {
                //If dealing with an array, process all the elements
                if (objChild is Array)
                {

                    for (int arrayCount = 0; arrayCount < (objChild as object[]).Length; arrayCount++)
                    {
                        returnedObj = SetPropertyToNull((objChild as object[])[arrayCount], remainingPropertyName, propertyValues, setFatherToNull);
                        (objChild as object[])[arrayCount] = returnedObj;
                    }
                    returnedObj = objChild;
                }
                //otherwise process the remaining object tree
                else
                {
                    if (!String.IsNullOrEmpty(remainingPropertyName))
                    {
                        returnedObj = SetPropertyToNull(objChild, remainingPropertyName, propertyValues, setFatherToNull);
                    }
                }
                initType.InvokeMember(childPropertyName,
                            BindingFlags.SetProperty, null, obj, new Object[] { returnedObj });
            }
            return obj;
        }

    public static void Main()
    {
        Type3 obj = new Type3();
        WL("Before...");
        obj.PrintMe();
        SetPropertyToNull(obj, "Value22.Value2", null, true);
        WL("After");
        obj.PrintMe();   
        RL();
    }
    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }
    private static void RL()
    {
        Console.ReadLine();   
    }
    private static void Break()
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

No comments: