System.Linq.Expressions中是否存在设计缺陷? [英] Is there a design flaw in System.Linq.Expressions?

查看:65
本文介绍了System.Linq.Expressions中是否存在设计缺陷?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用Linq设计函数解析器。乍一看,这看起来很有希望。我将能够以下列形式输出用户定义的预编译函数:

I have been working on designing a function parser using Linq. At first glance this looked as a promising prospect. I would be able to output user defined precompiled functions in the form:

Func<double, double> CustomFunction = ParseAndCompile(string ExpressionString);



然后我可以绘制图形:


I would then be able to draw a graph:

for (double x = minX; x < maxX; x += resolution)
{
    curve.Plot(x, CustomFunction(x));
}



我觉得很整洁。所以我创建了一些函数来测试这个概念(我不会打扰你的基类):


Pretty neat I thought. So I created a few functions to test out the concept (I won’t bother you with the base class):

// Binary function
public class Pow : Function
{
    public Pow()
    {
        Domain = FunctionDomain.Positive;
        Expression<Func<double, double, double>> func = (x, y) => Math.Pow(x, y);
        BinaryFunction = func.Compile();
        Name = "^";
    }
}

// Unary function
public class Abs : Function
{
    public Abs()
    {
        Domain = FunctionDomain.R;
        Expression<Func<double, double>> func = (x) => Math.Abs(x);
        UnaryFunction = func.Compile();
        Name = "Abs";
    }
}



我知道System.Linq.Expressions实现了Pow功能,但实际上这或多或少证明了我的观点。为什么要实施?因为Pow是常用的。但为何停在那里?为什么不在表达式中重新实现整个Math类?这肯定会对我有所帮助。因为在解析函数表达式之后,我无法调用任何整齐的一元和二元函数。为什么?



无法获得ParameterExpression的值!



为了显示我的意思,让我们看一下ParseAndCompile函数内部的内容。我不想专注于解析内容,所以我只展示与问题相关的内容:


I know that System.Linq.Expressions implements the Pow function, but this actually more or less proves my point. Why is it implemented? Because Pow is commonly used. But why stop there? Why not re-implement the whole Math class in Expressions? That would certainly help me. Because there is no way I can ever call any of my neat unary and binary functions after parsing a function expression. Why?

It is not possible to get the value of a ParameterExpression!

To show what I mean let’s look at what would go inside the ParseAndCompile function. I don’t want to focus on the parsing stuff, so I only show what is relevant for the problem:

List<Expression> expressions = new List<Expression>();
ParameterExpression x = Expression.Parameter(typeof(double), "x");
ParameterExpression result = Expression.Parameter(typeof(double), "result");
// Apply some function to x
expressions.Add(Expression.Assign(result, Expression.Constant(Functions.Tan(x))));
// Build expression
BlockExpression block = Expression.Block(new[] { result }, expressions);
// Compile the expression tree and return a delegate.
return Expression.Lambda<Func<double, double>>(block, x).Compile();



也似乎很整洁,问题是它不编译。 Functions.Tan(x))没有编译,因为Tan将double作为参数,x是ParameterExpression。没问题。我们可以取x的值。但不是!无法获取ParameterExpression的实际值。



为了记录,我是Linq的全新手,我可能错过了一些重点,但在我看来,事情并不完全尽可能简单。 Pow由Linq.Expressions实施的事实告诉我。为什么要提供它,如果我可以调用Math.Pow?


This also seems pretty neat, the problem is it doesn’t compile. Functions.Tan(x)) is not compiling because Tan takes a double as parameter and x is a ParameterExpression. No problem. We can just take the value of x. But no! There is no way to take the actual value of a ParameterExpression.

For the record I am a complete newbie to Linq and I am probably missing out on some important points, but it just seems to me, that something isn’t quite as simple as it could be. The fact that Pow is implemented by Linq.Expressions tells me that. Why provide it if I could just call Math.Pow?

推荐答案

不完全!!这是一个匿名函数。匿名函数甚至可以返回值。



not exactly!! this is an anonymous function. anonymous function can even return values.

public class Pow : Function
{
    public Pow()
    {
        Domain = FunctionDomain.Positive;
        Expression<Func<double, double, double>> func = (x, y) => { return Math.Pow(x, y)};
        BinaryFunction = func.Compile();
        Name = "^";
    }
}





看看它是否有效



see if it works


这篇关于System.Linq.Expressions中是否存在设计缺陷?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆