/// <summary>
/// Gets the better conversion (C# 4.0 spec, §7.5.3.3)
/// </summary>
/// <returns>0 = neither is better; 1 = t1 is better; 2 = t2 is better</returns>
public int BetterConversion(ResolveResult resolveResult, IType t1, IType t2)
{
LambdaResolveResult lambda = resolveResult as LambdaResolveResult;
if (lambda != null)
{
if (!lambda.IsAnonymousMethod)
{
t1 = UnpackExpressionTreeType(t1);
t2 = UnpackExpressionTreeType(t2);
}
IMethod m1 = t1.GetDelegateInvokeMethod();
IMethod m2 = t2.GetDelegateInvokeMethod();
if (m1 == null || m2 == null)
{
return(0);
}
int r = BetterConversionTarget(t1, t2);
if (r != 0)
{
return(r);
}
if (m1.Parameters.Count != m2.Parameters.Count)
{
return(0);
}
IType[] parameterTypes = new IType[m1.Parameters.Count];
for (int i = 0; i < parameterTypes.Length; i++)
{
parameterTypes[i] = m1.Parameters[i].Type.Resolve(context);
if (!parameterTypes[i].Equals(m2.Parameters[i].Type.Resolve(context)))
{
return(0);
}
}
if (lambda.HasParameterList && parameterTypes.Length != lambda.Parameters.Count)
{
return(0);
}
IType ret1 = m1.ReturnType.Resolve(context);
IType ret2 = m2.ReturnType.Resolve(context);
if (ret1.Kind == TypeKind.Void && ret2.Kind != TypeKind.Void)
{
return(1);
}
if (ret1.Kind != TypeKind.Void && ret2.Kind == TypeKind.Void)
{
return(2);
}
IType inferredRet = lambda.GetInferredReturnType(parameterTypes);
return(BetterConversion(inferredRet, ret1, ret2));
}
else
{
return(BetterConversion(resolveResult.Type, t1, t2));
}
}