Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用MethodCallExpression/lambda在树中从ConditionalExpression.if返回?_C#_Linq_Expression Trees - Fatal编程技术网

C# 如何使用MethodCallExpression/lambda在树中从ConditionalExpression.if返回?

C# 如何使用MethodCallExpression/lambda在树中从ConditionalExpression.if返回?,c#,linq,expression-trees,C#,Linq,Expression Trees,我试图让表达式树有条件地计算为字符串 以下是我迄今为止的代码: IQueryable<Category> myCategories = DataUtil.Categories.AsQueryable(); ParameterExpression categoryParameterExpression = Expression.Parameter(typeof (Category), "category"); MemberExpression categoryNameMemberEx

我试图让表达式树有条件地计算为字符串

以下是我迄今为止的代码:

IQueryable<Category> myCategories = DataUtil.Categories.AsQueryable();

ParameterExpression categoryParameterExpression = Expression.Parameter(typeof (Category), "category");
MemberExpression categoryNameMemberExpression = Expression.PropertyOrField(categoryParameterExpression, "CategoryName");
MemberExpression categoryNameLengthExpression = Expression.Property(categoryNameMemberExpression, typeof (string).GetProperty("Length"));
ConstantExpression constantLengthExpression = Expression.Constant(10, typeof (int));
BinaryExpression greaterThanLengthExpression = Expression.GreaterThan(categoryNameLengthExpression, constantLengthExpression);
var getNameInCapsMethod = typeof (Category).GetMethod("GetNameInCaps", BindingFlags.Instance | BindingFlags.Public);
MethodCallExpression getNameInCapsExpression = Expression.Call(categoryParameterExpression, getNameInCapsMethod, categoryNameMemberExpression);

ConditionalExpression ifGreaterThanLengthGetUpperNameExpression = Expression.IfThen(greaterThanLengthExpression, getNameInCapsExpression); 

// I need something between the lambda and the ConditionalExpression to ensure that the void type is not returned?

var ifGreaterThanLengthGetUpperNameLambdaExpression = Expression.Lambda<Func<Category, string>>(ifGreaterThanLengthGetUpperNameExpression, new ParameterExpression[] { categoryParameterExpression }); 
foreach (var category in myCategories)
{
    var upperName = ifGreaterThanLengthUpperLambda(category);
    System.Windows.MessageBox.Show(upperName);
}
IQueryable myCategories=DataUtil.Categories.AsQueryable();
ParameterExpression categoryParameterExpression=Expression.Parameter(类别的类型),“类别”);
MemberExpression CategoryNameExpression=Expression.PropertyOrField(categoryParameterExpression,“CategoryName”);
MemberExpression CategoryNameLengtheExpression=Expression.Property(categoryNameMemberExpression,typeof(string).GetProperty(“长度”);
ConstantExpression constantLengthExpression=表达式常数(10,typeof(int));
BinaryExpression greaterthangtheexpression=表达式。GreaterThan(类别名称表达式,常量表达式);
var getNameInCapsMethod=typeof(Category).GetMethod(“GetNameInCaps”,BindingFlags.Instance | BindingFlags.Public);
MethodCallExpression getNameInCapsExpression=Expression.Call(categoryParameterExpression、getNameInCapsMethod、categoryNameMemberExpression);
如果大于长度GetUpperNameExpression=表达式,则条件表达式为。如果大于长度表达式,则条件表达式为getNameInCapsExpression;
//我需要lambda和ConditionalExpression之间的一些东西来确保不返回void类型?
var ifGreaterThanLengthGetUpperNameLambdaExpression=Expression.Lambda(ifGreaterThanLengthGetUpperNameExpression,新参数表达式[]{categoryParameterExpression});
foreach(myCategories中的var类别)
{
var upperName=ifGreaterThanLengthUpperLambda(类别);
System.Windows.MessageBox.Show(大写);
}
以下是运行时发生的ArgumentException:

中发生类型为“System.ArgumentException”的未处理异常 System.Core.dll

其他信息:“System.Void”类型的表达式不能为空 用于返回类型“System.String”

我发现ConditionalExpression返回的是“IfFalse”条件的void类型

以下是我的表达式树可视化工具的屏幕截图:


我只需要字符串值。我意识到在ConditionalExpression类型上有一个表达式。IfThenElse,但我不确定在Else表达式中放什么。(如果可能的话,我不想只是传回一个空字符串。)有没有办法确保只有在前面的二进制表达式的计算结果为true时才计算条件?不管怎样,我该如何解决这个问题呢?

更全面地表达您真正想要实现的目标可能会有所帮助(基本上,您想要的表达式树的C#等价物是什么样子的)。目前,您的表达式树大致如下所示:

Func<Category, string> f = (category) => { 
    if (category.CategoryName.Length > 10) {
        category.GetNameInCaps(category.CategoryName);
    }
};
Func f=(类别)=>{
如果(category.CategoryName.Length>10){
category.GetNameInCaps(category.CategoryName);
}
};
但是,C#编译器不会编译它,因为您没有在任何代码路径上返回字符串,所以表达式树没有按照您希望的方式编译也就不足为奇了。至少有两个问题:

  • 您几乎肯定希望使用
    表达式.Condition,而不是
    表达式.IfThen
    。这将为您提供相当于
    语法,这是一个可以用作lambda返回值的表达式。作为一条语句,
    if(…){}
    块始终具有您发现的类型
    void
    (即使添加了
    else
    ,也是如此)
  • 你需要弄清楚当你的病情不稳定时该怎么办。如果确实需要返回字符串,则必须
    • 选择一些要返回的默认无意义值(例如
      null
      “”
      ),或
    • 抛出异常