对具有未知类的对象进行 LINQ 查询

本文关键字:LINQ 查询 对象 未知 | 更新日期: 2023-09-27 17:56:13

我有一个未知(对当前方法)类对象的数组。我知道每个类都有一个名为"数字"的属性。我正在尝试编写一个 LINQ 查询,在其中查找具有下一个数字的对象。又名,我在数字 8,使用 LINQ 查询查找 Number=9 的对象。

有人有建议吗?

另外,我经常使用反射,所以不用担心避免它。

对具有未知类的对象进行 LINQ 查询

您可以创建一个接口 - 带有属性编号的 INumber。数组中的每个对象都可以实现此接口。

这样,您将拥有一个已知类型的 INumber 数组。这样,您的查询将易于调试和维护。

如果对象都继承自已知接口,那么您可以强制转换它们,例如

var next = items.Cast<IHasNumber>.FirstOrDefault(x => x.Number == index + 1);

如果他们不这样做,那么你可以使用dynamic,例如

var next = items.Cast<dynamic>.FirstOrDefault(x => x.Number == index + 1);

如果你可以控制这些类型,那么我会让它们实现一个接口,以便你可以使用第一种方法,它应该比第二种方法快得多。在这种情况下,您的收藏可能一开始就IEnumerable<IHasNumber>,您甚至不必投掷。

如果正如您在其他地方指出的那样,您设计了所有类,那么您可以将该数字属性放在 in 接口中,并让所有类实现该接口。然后,在 linq 查询中,使用该接口。

如果您确实没有可以简化为的通用类型,并且由于某种原因无法引入此类类型,那么您可以使用 dynamic 关键字。 我目前无法访问编译器,但是您的方法可以接受动态对象的集合并查询它们吗?

例如:

IEnumerable<dynamic> collection = ...;
var numbers = from x in collection
              select x.Number;

若要避免性能问题,可以使用以下方法:

static void Main(string[] args)
{
    object[] objs = GetInitialData();
    var accessor = GetGetterHelper<int>(objs[0].GetType(), "Number");
    var res = from a in objs where accessor(a) == 7 select a;
}
static Func<object, T> GetGetterHelper<T>(Type type, string methodName)
{
    var methodInfo = type.GetProperty(methodName).GetGetMethod();
    return x => (T)methodInfo.Invoke(x, new object[] {});
}