- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个系统应该根据另一个应用程序提供的排序数据列表创建排序表达式。排序信息作为包含排序键 (Object.thingtosort) 和方向的对象给出。
我当前的解决方案是围绕我从另一个堆栈溢出问题得到的解决方案构建的,可在此处找到:original question .每当我运行以下代码时:
static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
Expression body = parameter;
foreach (var propName in propertyNames)
body = Expression.Property(body, propName);
var func = Expression.Lambda<Func<T, object>>(body, parameter); //<-- line of error
return func;
}
我得到错误:
System.ArgumentException: 'Expression of type 'System.Int32' cannot be used for return type 'System.Object''
我尝试通过使用将参数转换为对象来解决此问题
Expression.Convert(body, typeof(object));
导致以下功能:
static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
Expression body = parameter;
foreach (var propName in propertyNames)
body = Expression.Property(body, propName);
var convertedBody = Expression.Convert(body, typeof(object));
var func = Expression.Lambda<Func<T, object>>(convertedBody, parameter); //<-- line of error
return func;
}
这会产生另一个问题,它无法比较数组中的两个元素(可能是因为在这种情况下它不知道如何比较对象)。
System.InvalidOperationException: 'Failed to compare two elements in the array.'
ArgumentException: At least one object must implement IComparable.
我希望它适用于任何类型,因为排序应该适用于我的对象的任何字段(这些可以嵌套多层)。下面包含了重现我的问题所需的完整代码。
Microsoft Visual Studio Community 2022(64 位)- 预览版版本 17.3.0 预览 1.1
该项目是一个使用 .net 6 的控制台应用程序。
using System.Linq.Expressions;
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
string propertyForExpression = "Product.randomNumber";
Random random = new Random();
List<OrderEntity> orders = new List<OrderEntity>();
for (int i = 1; i < 11; i++)
{
var orderToAdd = new OrderEntity();
orderToAdd.id = i;
orderToAdd.name = "order number " + i;
var productToAdd = new ProductEntity();
productToAdd.id = i;
productToAdd.productName = "product " + i;
productToAdd.description = "this is a product";
productToAdd.randomNumber = random.Next(1, 100);
orderToAdd.Product = productToAdd;
orders.Add(orderToAdd);
}
var sortedOrders = orders.OrderBy(X => ToLambda<OrderEntity> (propertyForExpression));
foreach(var order in sortedOrders)
{
Console.WriteLine(order.Product.randomNumber);
}
Console.ReadKey();
}
static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
Expression body = parameter;
foreach (var propName in propertyNames)
body = Expression.Property(body, propName);
var func = Expression.Lambda<Func<T, object>>(body, parameter);
return func;
}
// ToLambda function that crashes on the OrderBy with error: System.InvalidOperationException: 'Failed to compare two elements in the array.'
//static Expression<Func<T, object>> ToLambda<T>(string propertyName)
//{
// var propertyNames = propertyName.Split('.');
// var parameter = Expression.Parameter(typeof(T));
// Expression body = parameter;
// foreach (var propName in propertyNames)
// body = Expression.Property(body, propName);
// var convertedBody = Expression.Convert(body, typeof(object));
// var func = Expression.Lambda<Func<T, object>>(convertedBody, parameter);
// return func;
//}
}
public class OrderEntity
{
public int id { get; set; }
public string name { get; set; }
public ProductEntity Product { get; set; }
}
public class ProductEntity
{
public int id { get; set; }
public string productName { get; set; }
public string description { get; set; }
public int randomNumber { get; set; }
}
最佳答案
这似乎最终是一个小错误。
Expression<Func<T, object>>
订购(与那个值一样,不是 randomNumber
的值决定排序顺序。.OrderBy
对于枚举(不可查询)期望一个 Func<TSource, TKey>
其中 TSource
是OrderEntity
和 TKey
应该是你的 object
在这种情况下的值(value)。所以我们需要做两件事:
本质上我们需要这个
Func<OrderEntity, object> sortAccessor = ToLambda<OrderEntity>(propertyForExpression).Compile();
var sortedOrders = orders.OrderBy(sortAccessor);
或
Func<OrderEntity, object> sortAccessor = ToLambda<OrderEntity>(propertyForExpression).Compile();
var sortedOrders = orders.OrderBy(x => sortAccessor(x));
或
var sortedOrders = orders.OrderBy(x => ToLambda<OrderEntity>(propertyForExpression).Compile()(x));
或
var sortedOrders = orders.OrderBy(ToLambda<OrderEntity>(propertyForExpression).Compile());
您还可以更改方法以返回已编译的 Func<T, object>
相反:
static Expression<Func<T, object>> ToLambda<T>(string propertyName)
{
var propertyNames = propertyName.Split('.');
var parameter = Expression.Parameter(typeof(T));
Expression body = parameter;
foreach (var propName in propertyNames)
body = Expression.Property(body, propName);
var convertedResult = Expression.Convert(body, typeof(object));
var func = Expression.Lambda<Func<T, object>>(convertedResult, parameter);
return func;
}
然后像这样使用它:
Func<OrderEntity, object> sortAccessor = ToLambda<OrderEntity>(propertyForExpression);
var sortedOrders = orders.OrderBy(sortAccessor);
或者这个:
var sortedOrders = orders.OrderBy(ToLambda<OrderEntity>(propertyForExpression));
注意:我建议在循环外编译表达式并将其缓存为 Func<OrderEntity, object>
的原因变量是因为否则它将针对单个 .OrderBy
进行多次评估.
关于c# - 从字符串构建 Linq 排序表达式结果为 'Expression of "system.int3 2"can not be used for return type "System.Object"',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72614282/
我正在尝试使用 y 组合器在 Scala 中定义 gcd: object Main { def y[A,B]( f : (A => B) => A => B ) : A => B = f(y(f)
我正在尝试了解返回指向函数的指针的函数,在我尝试编译代码后,它给了我这种错误: cannot convert int (*(int))(int) to int (*(int))(int) in ass
所以我一直在关注 youtube 上的游戏编程教程,然后弹出了这段代码:bufferedImageObject.getRGB(int, int, int, int, int[], int, int);
我正在将时间现在 与存储在数据库某处的时间进行比较。数据库中存储的时间格式为“yyyyMMddHHmmss”。例如,数据库可能会为存储的时间值返回 201106203354。然后我使用一个函数将时间现
例如 Maze0.bmp (0,0) (319,239) 65 120 Maze0.bmp (0,0) (319,239) 65 120 (254,243,90) Maze0.bmp (0,0) (
评论 Steve Yegge的post关于 server-side Javascript开始讨论语言中类型系统的优点和这个 comment描述: ... examples from H-M style
我正在研究 C 的指针,从 Deitel 的书中我不明白 int(*function)(int,int) 和 int*function(int, int) 表示函数时。 最佳答案 C 中读取类型的经验
您好,我使用 weblogic 11g 创建 war 应用程序,我对 joda time 的方法有疑问 new DateTime(int, int, int, int, int, int); 这抛出了
Create a method called average that calculates the average of the numbers passed as parameters. The
var a11: Int = 0 var a12: Int = 0 var a21: Int = 0 var a22: Int = 0 var valueDeterminant = a11 * a12
我正在为一个项目设置 LED 阵列。我得到了一个 LED 阵列,可以根据引脚变化电压进行更改,但我无法添加更多引脚。 当我尝试时,编译失败并显示错误:函数“int getMode(int, int,
除了创建对列表执行简单操作的函数之外,我对 haskell 还是很陌生。我想创建一个列表,其中包含 Int 类型的内容, 和 Int -> Int -> Int 类型的函数. 这是我尝试过的: dat
这个问题已经有答案了: Java add buttons dynamically as an array [duplicate] (4 个回答) 已关闭 7 年前。 StackOverFlow问题今天
我有几个 EditText View ,我想在其中设置左侧的图像,而 setCompoundDrawablesWithIntrinsicBounds 似乎不起作用。图形似乎没有改变。 有人知道为什么会
#include using namespace std; int main() { static_assert(is_constructible, int(*)(int,int)>::val
fun sum(a: Int, b: Int) = a + b val x = 1.to(2) 我在找: sum.tupled(x),或者 sum(*x) 当然,以上都不能用 Kotlin 1.1.3
有一个函数: func (first: Int) -> Int -> Bool -> String { return ? } 返回值怎么写?我对上面 func 的返回类型感到很困惑。 最
type foo = A of int * int | B of (int * int) int * int 和 (int * int) 有什么区别?我看到的唯一区别在于模式匹配: let test_
我正在尝试制作一个 slider 游戏。在这个类中,我使用 Graphics 对象 g2 的 drawImage 方法来显示“拼图”的 block 。但在绘制类方法中,我收到此错误:找不到符号方法dr
我试着理解这个表达: static Func isOdd = i => (i & 1) == 1; 但是这是什么意思呢? 例如我有 i = 3。然后 (3 & 1) == 1 或 i = 4。然后
我是一名优秀的程序员,十分优秀!