private bool HasArrayConversionToInterface(ArrayType pSource, CType pDest)
{
Debug.Assert(pSource != null);
Debug.Assert(pDest != null);
if (!pSource.IsSZArray)
{
return(false);
}
if (!pDest.isInterfaceType())
{
return(false);
}
// * From a single-dimensional array type S[] to IList<T> or IReadOnlyList<T> and their base
// interfaces, provided that there is an implicit identity or reference
// conversion from S to T.
// We only have six interfaces to check. IList<T>, IReadOnlyList<T> and their bases:
// * The base interface of IList<T> is ICollection<T>.
// * The base interface of ICollection<T> is IEnumerable<T>.
// * The base interface of IEnumerable<T> is IEnumerable.
// * The base interface of IReadOnlyList<T> is IReadOnlyCollection<T>.
// * The base interface of IReadOnlyCollection<T> is IEnumerable<T>.
if (pDest.isPredefType(PredefinedType.PT_IENUMERABLE))
{
return(true);
}
AggregateType atsDest = (AggregateType)pDest;
AggregateSymbol aggDest = atsDest.getAggregate();
if (!aggDest.isPredefAgg(PredefinedType.PT_G_ILIST) &&
!aggDest.isPredefAgg(PredefinedType.PT_G_ICOLLECTION) &&
!aggDest.isPredefAgg(PredefinedType.PT_G_IENUMERABLE) &&
!aggDest.isPredefAgg(PredefinedType.PT_G_IREADONLYCOLLECTION) &&
!aggDest.isPredefAgg(PredefinedType.PT_G_IREADONLYLIST))
{
return(false);
}
Debug.Assert(atsDest.GetTypeArgsAll().Count == 1);
CType pSourceElement = pSource.GetElementType();
CType pDestTypeArgument = atsDest.GetTypeArgsAll()[0];
return(HasIdentityOrImplicitReferenceConversion(pSourceElement, pDestTypeArgument));
}