Question

I try to find the way for refactoring my code but no idea how to do this.

For example, we have several classes

class A {
     string name;
     int year;
}

class B {
      long id;
      string code; 
      DateTime currentTime;
}

class C {
      string lastname;
      DateTime currentDate; 
}

And latter I need to return list of objects of these classes List, List, List and convert them into Object[][].

For every conversion I do the same

private Object[][] converAListToObjectArray(List<A> dataList)
        {
            long countRecords = dataList.Count();
            const int countProperty = 2;
            var arrayRes = new object[countRecords][];

            for (int i = 0; i < countRecords; i++)
            {
                var arrayObjProperty = new object[countProperty];
                arrayObjProperty[0] = dataList[i].Name;
                arrayObjProperty[1] = dataList[i].Year;

                arrayRes[i] = arrayObjProperty;
            }
            return arrayRes;
        }

private Object[][] converBListToObjectArray(List<B> dataList)
        {
            long countRecords = dataList.Count();
            const int countProperty = 3;
            var arrayRes = new object[countRecords][];

            for (int i = 0; i < countRecords; i++)
            {
                var arrayObjProperty = new object[countProperty];
                arrayObjProperty[0] = dataList[i].Id;
                arrayObjProperty[1] = dataList[i].Code;
                arrayObjProperty[2] = dataList[i].CurrentTime; 

                arrayRes[i] = arrayObjProperty;
            }
            return arrayRes;
        }

Is it possible separate this convertion using some design pattern?

Was it helpful?

Solution 2

You could use an action and do something like this: -

class Program
{
    // Your new function, (doesn't have to be static; just did it for the demo)
    // If you really really want to return object[][] still,
    // You'll need to pass an index to foo as well
    private static List<IList<object>> convert<T>(IList<T> dataList, Action<IList<object>, T> foo)
    {
        var arrayRes = new List<IList<object>>();

        foreach (var item in dataList)
        {
            var arrayObjProperty = new List<object>();
            foo(arrayObjProperty, item);

            arrayRes.Add(arrayObjProperty);
        }
        return arrayRes;
    }

    // The rest is just calling the function with two examples
    static void Main(string[] args)
    {
        var bar = new List<A>();
        bar.Add(new A() { name = "qux", year = 2013 });

        var objects1 = convert(bar, (a, b) =>
        {
            a.Add(b.name);
            a.Add(b.year);
        });

        var baz = new List<B>();
        baz.Add(new B() { code = "qux", id = 2013 });

        var objects2 = convert(baz, (a, b) =>
        {
            a.Add(b.code);
            a.Add(b.id);
        });
    }
}

You can just copy this into your IDE to have a play and see how it works. Basically, this uses generics and then an action to allow you to do the only part that differs each time in a lambda that is passed to the method.

OTHER TIPS

You could write a generic function which uses reflection to get each object's field names and values. You'd need to decide whether it should work for public or private fields. The example below grabs both the public and the private fields:

static object[][] ConvertToObjectArray<T>(IList<T> objects)
{
    var fields = (from fieldInfo in typeof(T).GetFields(
        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                  orderby fieldInfo.Name
                  select fieldInfo).ToArray();

    object[][] table = new object[objects.Count][];
    for (int i = 0; i < table.Length; i++)
    {
        table[i] = (from fieldInfo in fields
                    select fieldInfo.GetValue(objects[i])).ToArray();
    }
    return table;
}

You could simplify and use something like this - e.g. for B...

List<B> list = new List<B> 
{
    new B{ id = 1, code = "", currentTime = DateTime.Now},
    new B{ id = 1, code = "", currentTime = DateTime.Now},
    new B{ id = 1, code = "", currentTime = DateTime.Now},
};

var array = list.Select(x => new object[] { x.id, x.code, x.currentTime }).ToArray();

Your Object[][] structure is a little unusual to my eye. Did you know there's a Cast method for lists?

You can do the following:

List<A> foo = new List<A> ();

// initialize foo here
var bar = foo.Cast<Object>().ToArray();

Which will get you a an array of objects with your field names intact. If you absolutely need to have the fields as array elements (why do you want this) you could add a ToObject method to each of your classes:

class A
{
    public string name;
    public int year;
    public Object[] ToObject()
    {
        return new Object[] {name, year};
    }
}


    List<A> foo = new List<A>
    {
        new A{name="reacher",year=2013},
        new A{name="Ray",year=2013}
    }; 
    var bux = foo.Select(a => a.ToObject()).ToArray() ;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top