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.
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();
.