I have created a class which has a method which is overloaded to accept a class or a collection of classes.
The problem is that the wrong overload is called for different types of collections. An example of this can be seen using this sample code I've created:
void Main()
{
GenericMethod(x => x.CollectionItems, ExpectedType.Collection);
GenericMethod(x => x.ListItems, ExpectedType.Collection);
GenericMethod(x => x.EnumerableItems, ExpectedType.Collection);
GenericMethod(x => x.CollectionTestSubClass, ExpectedType.Single);
}
public void GenericMethod<TPropType>(Expression<Func<CollectionTestClass, TPropType>> predicate, ExpectedType expectedType)
where TPropType : class
{
$"Single Method Called - Expected: {expectedType}".Dump();
}
public void GenericMethod<TPropType>(Expression<Func<CollectionTestClass, IEnumerable<TPropType>>> predicate, ExpectedType expectedType)
where TPropType : class
{
$"Collection Method Called - Expected: {expectedType}".Dump();
}
public class CollectionTestClass
{
public Guid Id { get; set; }
public ICollection<CollectionTestSubClass> CollectionItems { get; set; }
public IList<CollectionTestSubClass> ListItems { get; set; }
public IEnumerable<CollectionTestSubClass> EnumerableItems { get; set; }
public CollectionTestSubClass CollectionTestSubClass { get; set; }
}
public class CollectionTestSubClass
{
public Guid Id { get; set; }
}
public enum ExpectedType
{
Single,
Collection
}
The output will be:
So it is only the IEnumerable that will call the correct Collection
method.
I would have thought that with ICollection and IList being implementations of IEnumerable that it may be able to figure out which method to call. Or is it a case that generics in C# are constraining to the point that even though other collections do implement IEnumerable
it is only going to allow the explicit class specified to be used?
In which case would I have to write a overload for each collection type?