/// <summary> /// Equality is based on an exact match of <see cref="Kind"/> and <see cref="NullableProfile"/> /// but also handles the case when one of the two is oblivious of NRT and the other is <see cref="NullablityTypeKindExtension.IsNRTFullNullable(NullabilityTypeKind)"/>. /// </summary> /// <param name="other">The other info.</param> /// <returns>True if this is equal to other, false otherwise.</returns> public bool Equals(NullabilityTypeInfo other) { Debug.Assert(Kind != other.Kind || ((_profile == null) == (other._profile == null)), "If Kind are equals then both have a profile or not."); // Strict equality. if (Kind == other.Kind && (_profile == null || _profile.SequenceEqual(other._profile !))) { return(true); } // Basic type properties must be the same. if ((Kind & (~NullabilityTypeKind.NRTFullNonNullable | NullabilityTypeKind.NRTFullNullable)) != (other.Kind & (~NullabilityTypeKind.NRTFullNonNullable | NullabilityTypeKind.NRTFullNullable))) { return(false); } // If this is a Full NRT nullable and the other is not NRT aware it is necessarily nullable since this is a reference type and // other has the same basic type kind, it is nullable by default. if (Kind.IsNRTFullNullable() && !other.Kind.IsNRTAware()) { Debug.Assert(other.Kind.IsReferenceType() && other.Kind.IsNullable()); return(true); } // Reverse the previous check. if (other.Kind.IsNRTFullNullable() && !Kind.IsNRTAware()) { Debug.Assert(Kind.IsReferenceType() && Kind.IsNullable()); return(true); } return(false); }