Lambda 如何调用使用C+中的System::Linq::Expressions::Expression的函数+/CLI?

Lambda 如何调用使用C+中的System::Linq::Expressions::Expression的函数+/CLI?,lambda,c++-cli,Lambda,C++ Cli,在我的C++/CLI应用程序中,我使用的是一个库(NHibernate),它有许多函数采用System::Linq::Expressions::Expression(如QueryOver的Where()方法) 用C#,我可以写: public IEnumerablecatsByName(字符串名) { 返回会话。查询版本() 其中(c=>c.Name==Name)/(); } 显然,我不能在C++/CLI中使用这种语法,但我认为lambda只是变成了匿名委托,我可以设置一个委托来进行等效的比较

在我的C++/CLI应用程序中,我使用的是一个库(NHibernate),它有许多函数采用System::Linq::Expressions::Expression(如QueryOver的
Where()
方法)

用C#,我可以写:

public IEnumerablecatsByName(字符串名)
{
返回会话。查询版本()
其中(c=>c.Name==Name)/();
}
显然,我不能在C++/CLI中使用这种语法,但我认为lambda只是变成了匿名委托,我可以设置一个委托来进行等效的比较,并将其传递给
Where()
。它不起作用。相反,我得到了以下编译错误:

1>cats.cpp(54):错误C2664:'NHibernate::IQueryOver^NHibernate::IQueryOver::Where(System::Linq::Expressions::Expression^)':无法将参数1从'System::Func^'转换为'NHibernate::Criterian::ICriterion^'
1> 没有可用的用户定义的转换运算符,或
1> 指向的类型是不相关的;转换需要重新解释转换、C样式转换或函数样式转换

如何调用这些函数?

首先要了解的是,lambda表达式不仅会转换为匿名委托。如果它们遵循某些规则,它们也可以是,这是NHibernate的
Where()
方法所需要的,由其单个参数的类型指定:

System::Linq::Expressions::Expression< System::Func< T, bool > >
所以你可以看到这很难看。您正在手动构建表达式树,而在C#中,编译器会为您执行此操作。另外,请注意,使用lambda表达式在C#中构建表达式树的一个主要好处是可以对属性进行编译时类型检查。在C++/CLI中,您不会得到这样的结果,因为您必须在运行时按名称获取类属性,这是通过字符串完成的


底线是,在C++/CLI中确实可以调用带有
表达式
参数的函数,但这比在C#中要困难得多,繁琐得多,而且容易出错,而且您并没有真正获得任何好处。如果有其他选择,你可能会更好地使用它。幸运的是,NHibernate就是这种情况。

首先要了解的是,lambda表达式不仅会变成匿名委托。如果它们遵循某些规则,它们也可以是,这是NHibernate的
Where()
方法所需要的,由其单个参数的类型指定:

System::Linq::Expressions::Expression< System::Func< T, bool > >
所以你可以看到这很难看。您正在手动构建表达式树,而在C#中,编译器会为您执行此操作。另外,请注意,使用lambda表达式在C#中构建表达式树的一个主要好处是可以对属性进行编译时类型检查。在C++/CLI中,您不会得到这样的结果,因为您必须在运行时按名称获取类属性,这是通过字符串完成的


底线是,在C++/CLI中确实可以调用带有
表达式
参数的函数,但这比在C#中要困难得多,繁琐得多,而且容易出错,而且您并没有真正获得任何好处。如果有其他选择,你可能会更好地使用它。幸运的是,NHibernate就是这样。

NHibernate团队依靠友好的VB.NET或C#编译器将这些表达式自动转换为System::Linq::Expression。它不是C++/CLI编译器的一个特性,它的时钟在2005年停止了滴答滴答的运行,并且从未得到Linq的喜爱。你必须自己建造它们。非常痛苦,请使用拆装器作为指导。但您肯定希望利用著名的.NET语言互操作性,并将其写入一个单独的C++项目中,供您在C++/CLI项目中引用。NHibernate团队依靠友好的VB.NET或C编译器将这些表达式自动转换为System::Linq::Expression。它不是C++/CLI编译器的一个特性,它的时钟在2005年停止了滴答滴答的运行,并且从未得到Linq的喜爱。你必须自己建造它们。非常痛苦,请使用拆装器作为指导。但您肯定希望利用著名的.NET语言互操作性,并将其写入一个单独的C#项目中,您可以在C++/CLI项目中引用该项目。