public ResolveResult ResolveConditional(ResolveResult condition, ResolveResult trueExpression, ResolveResult falseExpression)
{
// C# 4.0 spec §7.14: Conditional operator
bool isValid;
IType resultType;
if (trueExpression.Type.Kind == TypeKind.Dynamic || falseExpression.Type.Kind == TypeKind.Dynamic) {
resultType = SpecialType.Dynamic;
isValid = TryConvert(ref trueExpression, resultType) & TryConvert(ref falseExpression, resultType);
} else if (HasType(trueExpression) && HasType(falseExpression)) {
Conversion t2f = conversions.ImplicitConversion(trueExpression, falseExpression.Type);
Conversion f2t = conversions.ImplicitConversion(falseExpression, trueExpression.Type);
// The operator is valid:
// a) if there's a conversion in one direction but not the other
// b) if there are conversions in both directions, and the types are equivalent
if (IsBetterConditionalConversion(t2f, f2t)) {
resultType = falseExpression.Type;
isValid = true;
trueExpression = Convert(trueExpression, resultType, t2f);
} else if (IsBetterConditionalConversion(f2t, t2f)) {
resultType = trueExpression.Type;
isValid = true;
falseExpression = Convert(falseExpression, resultType, f2t);
} else {
resultType = trueExpression.Type;
isValid = trueExpression.Type.Equals(falseExpression.Type);
}
} else if (HasType(trueExpression)) {
resultType = trueExpression.Type;
isValid = TryConvert(ref falseExpression, resultType);
} else if (HasType(falseExpression)) {
resultType = falseExpression.Type;
isValid = TryConvert(ref trueExpression, resultType);
} else {
return ErrorResult;
}
condition = ResolveCondition(condition);
if (isValid) {
if (condition.IsCompileTimeConstant && trueExpression.IsCompileTimeConstant && falseExpression.IsCompileTimeConstant) {
bool? val = condition.ConstantValue as bool?;
if (val == true)
return trueExpression;
else if (val == false)
return falseExpression;
}
return new OperatorResolveResult(resultType, System.Linq.Expressions.ExpressionType.Conditional,
condition, trueExpression, falseExpression);
} else {
return new ErrorResolveResult(resultType);
}
}