MoreThanChaos
MoreThanChaos

Reputation: 2092

How can I remove duplication between methods that differ only on type but use non-default constructors?

Hello I got many methods (below 2 examples) that look almost exactly the same. The difference is in name of JSON breanch that is processed, type of returned list and type of objects added to list. I know these example methods yet needs some optimization in its body, but the case is to pass type of returned value and type of class which method currently need and make it all work. If it is possible I would like to avoid casting in place of calling method.

Method 1

    public static List<Box> JsonToListOfBoxes(string data)
    {
        List<Box> ListOfBoxes = new List<Box>();
        if(!string.IsNullOrEmpty(data))
        {
            JObject productsJson = JObject.Parse(data);
            JToken jtkProduct;

            jtkProduct = productsJson["boxes"];

            if(jtkProduct != null)
                if(jtkProduct.HasValues)
                {
                    int childrenCount = productsJson["boxes"].Count();
                    for(int x = 0;x < childrenCount;x++)
                        ListOfBoxes.Add(new Box(productsJson["boxes"][x]));
                }
        }

        return ListOfBoxes;
    }

Method 2

    public static List<Envelope> JsonToListOfEnvelopes(string data)
    {
        List<Envelope> ListOfEnvelopes = new List<Envelope>();
        if(!string.IsNullOrEmpty(data))
        {
            JObject productsJson = JObject.Parse(data);
            JToken jtkProduct;

            jtkProduct = productsJson["envelopes"];

            if(jtkProduct != null)
                if(jtkProduct.HasValues)
                {
                    int childrenCount = productsJson["envelopes"].Count();
                    for(int x = 0;x < childrenCount;x++)
                        ListOfEnvelopes.Add(new Envelope(productsJson["envelopes"][x]));
                }
        }

        return ListOfEnvelopes;
    }

Upvotes: 3

Views: 85

Answers (3)

Raj Karri
Raj Karri

Reputation: 551

I just changed @msmolcic logic a bit.

public static List<T> JsonToListOfBoxes<T>(string data)
{
    List<T> ListOfItems = new List<T>();
    string dataName = typeof(T) == typeof(Box) ? "boxes" : "envelopes";

      //if there are many types one can try in below way..
      // if (typeof(T) == typeof(Box))
      //  {
      //      dataName = "Box";
      //  }
      //  else if (typeof(T) == typeof(Envelope))
      //  {
      //      dataName = "envelopes";
      //  }

    if (!string.IsNullOrEmpty(data))
    {
        JObject productsJson = JObject.Parse(data);
        JToken jtkProduct;

        jtkProduct = productsJson[dataName];

        if (jtkProduct != null)
            if (jtkProduct.HasValues)
            {
                int childrenCount = productsJson[dataName].Count();
                for (int x = 0; x < childrenCount; x++)
                    ListOfItems.Add((T)Activator.CreateInstance(typeof(T), productsJson[dataName][x]));
            }
    }

    return ListOfItems;
}

Upvotes: 0

msmolcic
msmolcic

Reputation: 6557

You could make generic method where dataName should be "boxes" or "envelopes":

public static List<T> JsonToListOfBoxes<T>(string data, string dataName)
{
    List<T> ListOfItems = new List<T>();
    if (!string.IsNullOrEmpty(data))
    {
        JObject productsJson = JObject.Parse(data);
        JToken jtkProduct;

        jtkProduct = productsJson[dataName];

        if (jtkProduct != null)
            if (jtkProduct.HasValues)
            {
                int childrenCount = productsJson[dataName].Count();
                for (int x = 0; x < childrenCount; x++)
                    ListOfItems.Add((T)Activator.CreateInstance(typeof(T), productsJson[dataName][x]));
            }
    }

    return ListOfItems;
}

Use example:

var list1 = JsonToListOfBoxes<Box>("dataString", "boxes");
var list2 = JsonToListOfBoxes<Envelope>("dataString", "envelopes");

Upvotes: 1

Orion_Eagle
Orion_Eagle

Reputation: 134

Using generics you can change as follows : (without parameterized generic constructor)

    public static List<T> JsonToListOfEnvelopes<T>(string data, string searchString, Func<string, T> creator)
    {
        List<T> ListOfEnvelopes = new List<T>();
        if (!string.IsNullOrEmpty(data))
        {
            JObject productsJson = JObject.Parse(data);
            JToken jtkProduct;

            jtkProduct = productsJson[searchString];

            if (jtkProduct != null)
                if (jtkProduct.HasValues)
                {
                    int childrenCount = productsJson[searchString].Count();
                    for (int x = 0; x < childrenCount; x++)
                        ListOfEnvelopes.Add(creator(productsJson[searchString][x]));
                }
        }

        return ListOfEnvelopes;
    }

And you can call it as

        var result = JsonToListOfEnvelopes("data", "boxes", c => { return new Box(c); });
        var result = JsonToListOfEnvelopes("data", "envelopes", c => { return new Envelope(c); });

Upvotes: 5

Related Questions