I have a collection of objects which I pass as parameter to create objects of another type (one for one). I am doing this in many places (basically converting from data objects to business objects). I want to write a generic extension method to accomplish this. But I am stuck because I don't know how I can specify constraint that business object has a constructor taking data object as parameter. Following is code of my function:
public static IList<T> ConvertTo<A,T>(this IEnumerable<A> list)
where T : new(A)/*THIS IS PROBLEM PART*/
{
var ret = new List<T>();
foreach (var item in list)
{
ret.Add(new T(item));
}
return ret;
}
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
Declaring those constraints means you can use the operations and method calls of the constraining type. If your generic class or method uses any operation on the generic members beyond simple assignment or calling any methods not supported by System. Object, you'll apply constraints to the type parameter.
There can be more than one constraint associated with a type parameter. When this is the case, use a comma-separated list of constraints. In this list, the first constraint must be class or struct or the base class.
You can specify one or more constraints on the generic type using the where clause after the generic type name. The following example demonstrates a generic class with a constraint to reference types when instantiating the generic class.
Unfortunately, this isn't allowed in C#. You can have a new()
constraint that forces the type to have a default constructor, but that is the only constructor related constraint supported by .NET.
Your best option is probably to define an interface you can use, and constrain to the interface. Instead of trying to set the object at construction, you can have an "Initialize" style method that takes the "A" object, and call that.
You can't constrain generic type constructors in this way (only to require a parameterless constructor), but you could take a delegate to do the construction:
public static IList<T> ConvertTo<A, T>(this IEnumerable<A> list, Func<A, T> constructionFunc)
{
return list.Select(constructionFunc).ToList();
}
And use it like this:
var IList<T> converted = someSequence.ConvertTo(a => new T(a));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With