0

I have two models that can both use the function below. I created an Interface that both of these models implement.

In the function below I am looping through the passed in list and using the values in it to create a new version of the list.

public static IList<T> GenericFunction<T>(IList<T> objList) where T : IProduct
{
    // In this function I am doing the following:

    IList<T> retVal = new List<T>();

    foreach (T obj in objList)
    {
        T newObj = (T)Activator.CreateInstance(typeof(T));

        newObj.Price = obj.BasePrice + obj.OldPrice;
        newObj.Description = obj.Name + " " + obj.Description;

        retVal.add(newObj);
    }

    return retVal;
}

The above code is working, but I have a couple of questions:

In order to have a function like the above that works with any model that implements IProduct, doing what I did is my only option right? At first I was thinking I could just simply create a standard function that takes IList<IProduct> as a param and returns IList<IProduct>. But then I ran into the problem of instantiating a new object which led me to creating a Generic Function.

Additionally, can I use an object initializer on newObj to set its properties?

After seeing this StackOverflow post I feel like I should be doing something different.

Community
  • 1
  • 1
Blake Rivell
  • 13,105
  • 31
  • 115
  • 231

1 Answers1

4

If you know that IProduct will always have a paramterless constructor, you can achieve this through generic constraints:

public static IList<T> GenericFunction<T>(IList<T> objList) where T : IProduct, new()
{
    IList<T> retVal = new List<T>();

    foreach (T obj in objList)
    {
        T newObj = new T();
        newObj.Price = obj.BasePrice + obj.OldPrice;
        newObj.Description = obj.Name + " " + obj.Description;
        retVal.Add(newObj);
    }
    return retVal;
}

new() constrains T such that it must have a parameterless constructor - allowing it to be instantiated via T newObj = new T();.

TVOHM
  • 2,740
  • 1
  • 19
  • 29
  • Hmm I am getting the following intellisense error on: T newObj = new T(); cannot create an instance of the variable type T because it does not have the new() constraint. – Blake Rivell Mar 09 '16 at 16:46
  • 1
    Did you add the `where T : IProduct, new()` bit? – TVOHM Mar 09 '16 at 16:47
  • I missed that! Now it works. What exactly is adding new() telling it? So as long as it has a constructorless param I can do this right? – Blake Rivell Mar 09 '16 at 16:47
  • 1
    It is telling the compiler that the type `T` must have a constructor that takes no arguments, so it knows it is able to create it using `new T()`. – TVOHM Mar 09 '16 at 16:50