//////////////////////////////////////////////////////////////////////////////// private bool UpperBoundInterfaceInference(AggregateType pSource, CType pDest) { if (!pSource.isInterfaceType()) { return false; } // SPEC: Otherwise, if U is an interface CType C<U1...Uk> and V is a class CType // SPEC: or struct CType and there is a unique set V1...Vk such that V directly // SPEC: or indirectly implements C<V1...Vk> then an exact ... // SPEC: ... and U is an interface CType ... if (!pDest.isStructType() && !pDest.isClassType() && !pDest.isInterfaceType()) { return false; } var interfaces = pDest.AllPossibleInterfaces(); AggregateType pInterface = null; foreach (AggregateType pCurrent in interfaces) { if (pCurrent.GetOwningAggregate() == pSource.GetOwningAggregate()) { if (pInterface == null) { pInterface = pCurrent; } else if (pInterface != pCurrent) { // Not unique. Bail out. return false; } } } if (pInterface == null) { return false; } UpperBoundTypeArgumentInference(pInterface, pDest.AsAggregateType()); return true; }
//////////////////////////////////////////////////////////////////////////////// private bool LowerBoundInterfaceInference(CType pSource, AggregateType pDest) { if (!pDest.isInterfaceType()) { return false; } // SPEC: Otherwise, if V is an interface CType C<V1...Vk> and U is a class CType // SPEC: or struct CType and there is a unique set U1...Uk such that U directly // SPEC: or indirectly implements C<U1...Uk> then an // SPEC: exact, upper-bound, or lower-bound inference ... // SPEC: ... and U is an interface CType ... // SPEC: ... and U is a CType parameter ... //TypeArray pInterfaces = null; if (!pSource.isStructType() && !pSource.isClassType() && !pSource.isInterfaceType() && !pSource.IsTypeParameterType()) { return false; } var interfaces = pSource.AllPossibleInterfaces(); AggregateType pInterface = null; foreach (AggregateType pCurrent in interfaces) { if (pCurrent.GetOwningAggregate() == pDest.GetOwningAggregate()) { if (pInterface == null) { pInterface = pCurrent; } else if (pInterface != pCurrent) { // Not unique. Bail out. return false; } } } if (pInterface == null) { return false; } LowerBoundTypeArgumentInference(pInterface, pDest); return true; }