Reputation: 1180
I need to do somthing like below code, but new T() does not work. It says "Cannot create an instance of variable type T because it does not have a new() constraint."
public static T MapToBaseDropDown2<T>(this GenericDropDownData dd) where T : BaseDropDown
{
return new T() //FAILS
{
Id = dd.Id,
Description = dd.Description
};
}
BaseDropDown is the base class for 3 childs that are entities mapped with EntityFramework (code first), so it may be better keep it as simple as possible.
Now it is not abstract due to some implementations that I tried, but if possible it will be.
public class BaseDropDown
{
public int Id { get; set; }
public string Description { get; set; }
}
Upvotes: 2
Views: 179
Reputation: 1180
This also works, just adding the new()
constraint directly to T (not to BaseDropDown)
public static T MapToBaseDropDown3<T>(this GenericDropDownData dd) where T : BaseDropDown, new()
{
return new T()
{
Id = dd.Id,
Description = dd.Description
};
}
Upvotes: 2
Reputation: 37000
Calling new T()
assumes that every type has a parameterless-constructor, which doesn´t seem to be the case here. Even if your base-class BaseDropDown
has such a constructor that isn´t guranteed for all its subclasses, in particular abstract ones:
class BaseDropDown
{
public BaseDropDown() { /* see parameterless-constructor exists */ }
}
abstract class MyClass : BaseDropDown
{
public MyClass() { ... }
}
Now you could use the new
-constraint to exclude abstract classes:
public static T MapToBaseDropDown2<T>(this GenericDropDownData dd) where T : BaseDropDown, new()
That constraint will onlx allow classes that inherit BaseDropDown
and are instantiable using a parameterless constructor.
Upvotes: 2
Reputation: 1180
Using reflection works fine:
public static T MapToBaseDropDown2<T>(this GenericDropDownData dd) where T : BaseDropDown
{
T entityDd = (T)Activator.CreateInstance(typeof(T));
entityDd.Id = dd.Id;
entityDd.Description = dd.Description;
return entityDd;
}
Upvotes: -1
Reputation: 1514
The BaseDropDown
class needs to have the new()
constraint applied like this:
public class BaseDropDown<T> where T : SomeClass, new()
{
}
The new()
constraint must always be applied last. See here for more details.
Upvotes: 1