BinaryExpression.AndAlso
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 16.03.19 09:37
Оценка:
Хочу создать вызвать BinaryExpression.AndAlso с указанием своего метода (Exec_V_V)

class Op2_Code__AndAlso___Boolean__Boolean
{
 private static Boolean Exec_V_V(Boolean a,Boolean b)
 {
  return a && b;
 }//Exec_V_V
};//class Op2_Code__AndAlso___Boolean__Boolean


И никак — из BinaryExpression.AndAlso выкидывается исключение.
Полез в код (взял corefx с GitHUB). Там понакручено
  Раз
        public static BinaryExpression AndAlso(Expression left, Expression right, MethodInfo method)
        {
            ExpressionUtils.RequiresCanRead(left, nameof(left));
            ExpressionUtils.RequiresCanRead(right, nameof(right));
            Type returnType;
            if (method == null)
            {
                if (left.Type == right.Type)
                {
                    if (left.Type == typeof(bool))
                    {
                        return new LogicalBinaryExpression(ExpressionType.AndAlso, left, right);
                    }
                    else if (left.Type == typeof(bool?))
                    {
                        return new SimpleBinaryExpression(ExpressionType.AndAlso, left, right, left.Type);
                    }
                }
                method = GetUserDefinedBinaryOperator(ExpressionType.AndAlso, left.Type, right.Type, "op_BitwiseAnd");
                if (method != null)
                {
                    ValidateUserDefinedConditionalLogicOperator(ExpressionType.AndAlso, left.Type, right.Type, method);
                    returnType = (left.Type.IsNullableType() && TypeUtils.AreEquivalent(method.ReturnType, left.Type.GetNonNullableType())) ? left.Type : method.ReturnType;
                    return new MethodBinaryExpression(ExpressionType.AndAlso, left, right, returnType, method);
                }
                throw Error.BinaryOperatorNotDefined(ExpressionType.AndAlso, left.Type, right.Type);
            }
            ValidateUserDefinedConditionalLogicOperator(ExpressionType.AndAlso, left.Type, right.Type, method);
            returnType = (left.Type.IsNullableType() && TypeUtils.AreEquivalent(method.ReturnType, left.Type.GetNonNullableType())) ? left.Type : method.ReturnType;
            return new MethodBinaryExpression(ExpressionType.AndAlso, left, right, returnType, method);
        }

  Два
        private static void ValidateUserDefinedConditionalLogicOperator(ExpressionType nodeType, Type left, Type right, MethodInfo method)
        {
            ValidateOperator(method);
            ParameterInfo[] pms = method.GetParametersCached();
            if (pms.Length != 2)
                throw Error.IncorrectNumberOfMethodCallArguments(method, nameof(method));
            if (!ParameterIsAssignable(pms[0], left))
            {
                if (!(left.IsNullableType() && ParameterIsAssignable(pms[0], left.GetNonNullableType())))
                    throw Error.OperandTypesDoNotMatchParameters(nodeType, method.Name);
            }
            if (!ParameterIsAssignable(pms[1], right))
            {
                if (!(right.IsNullableType() && ParameterIsAssignable(pms[1], right.GetNonNullableType())))
                    throw Error.OperandTypesDoNotMatchParameters(nodeType, method.Name);
            }
            if (pms[0].ParameterType != pms[1].ParameterType)
            {
                throw Error.UserDefinedOpMustHaveConsistentTypes(nodeType, method.Name);
            }
            if (method.ReturnType != pms[0].ParameterType)
            {
                throw Error.UserDefinedOpMustHaveConsistentTypes(nodeType, method.Name);
            }
            if (IsValidLiftedConditionalLogicalOperator(left, right, pms))
            {
                left = left.GetNonNullableType();
            }
            Type declaringType = method.DeclaringType;
            if (declaringType == null)
            {
                throw Error.LogicalOperatorMustHaveBooleanOperators(nodeType, method.Name);
            }
            MethodInfo opTrue = TypeUtils.GetBooleanOperator(declaringType, "op_True");
            MethodInfo opFalse = TypeUtils.GetBooleanOperator(declaringType, "op_False");
            if (opTrue == null || opTrue.ReturnType != typeof(bool) ||
                opFalse == null || opFalse.ReturnType != typeof(bool))
            {
                throw Error.LogicalOperatorMustHaveBooleanOperators(nodeType, method.Name); // <---- Исключение генерируется здесь.
            }
            VerifyOpTrueFalse(nodeType, left, opFalse, nameof(method));
            VerifyOpTrueFalse(nodeType, left, opTrue, nameof(method));
        }

Проблема связана с op_True и op_False, которых нет в моем классе Op2_Code__AndAlso___Boolean__Boolean.

За каким так все накручено — не понимаю.

Я передаю два аргумента и метод с реализацией операции.

Максимум что надо было им (кодерам из MS) сделать — проверить допустимость вызова метода с этими аргументами.

Это можно как-то победить?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Отредактировано 16.03.2019 9:41 DDDX . Предыдущая версия . Еще …
Отредактировано 16.03.2019 9:39 DDDX . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.