【问题标题】:How to use expression constant with long or int64?如何在 long 或 int64 中使用表达式常量?
【发布时间】:2021-06-17 11:11:36
【问题描述】:

我有一个扩展方法

public static Expression<Func<T, bool>> ToExpression<T>(string operator, string name, object value)
{
    var parameter = Expression.Parameter(typeof(T));
    var memberExpression = Expression.Property(parameter, name);
    var constantExpression = Expression.Constant(value, typeof(memberExpression.Type));

    ....
    ..
    .
}

因此 Expression.Constant 会为此类数据引发异常:

我正在使用这个例如类:

public class Person{
    public    long Number{get;set;}
}

var person1 = new Person{ Number=123}
var person2 = new Person{ Number=9876543210}

person1 有效,但 person2 抛出异常“Argument types does not match”。

我该如何解决这个问题?

【问题讨论】:

  • 为什么你的参数value 的类型是string 而不是T
  • 我更新了帖子
  • 你能告诉我们你是如何使用ToExpression的吗?

标签: c# .net linq expression


【解决方案1】:

您必须在创建常量表达式之前转换值。

public static bool IsNullable(Type type)
{
    return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}

public static Type ToUnderlying(Type type)
{
    if (type == null) throw new ArgumentNullException(nameof(type));

    if (IsNullable(type)) type = type.GetGenericArguments()[0];
    if (type.IsEnum      ) type = Enum.GetUnderlyingType(type);

    return type;
}

public static bool SafeConvert(object value, Type type, out object newValue)
{
    newValue = value;
    if (value == null)
    {
        if (!IsNullable(type))
            return false;
        return true;
    }

    var fromType = value.GetType();

    if (fromType == type)
        return true;

    if (IsNullable(type))
    {
        type = ToUnderlying(type);
    }

    newValue = Convert.ChangeType(value, type);
    return true;
}

public static Expression<Func<T, bool>> ToFilterExpression<T>(string operatorStr, string name, object value)
{
    var parameter = Expression.Parameter(typeof(T));
    var memberExpression = Expression.Property(parameter, name);

    if (!SafeConvert(value, memberExpression.Type, out var convertedValue))
        throw new Exception($"Cannot convert '{value}' to type '{memberExpression.Type.Name}'.");

    var constantExpression = Expression.Constant(convertedValue, memberExpression.Type);

    ...
}

【讨论】:

  • 你为什么使用if (memberExpression.Type != typeof(string))条件?
  • 我将值参数字符串的帖子更新为对象。你能更新答案吗?
  • 更新到对象。
  • 这次会抛出可空参数。如果 Number 属性很长?,从 system.int32 到 syste.nullable'[system.int32.
  • 好吧,没有完成转换。今天晚些时候将准备转换。
猜你喜欢
  • 2014-07-04
  • 1970-01-01
  • 2020-03-03
  • 1970-01-01
  • 2017-10-31
  • 2011-02-13
  • 2013-10-10
  • 2012-08-16
  • 1970-01-01
相关资源
最近更新 更多