C# 具有未知类的对象的LINQ查询

C# 具有未知类的对象的LINQ查询,c#,vb.net,linq,reflection,.net-3.5,C#,Vb.net,Linq,Reflection,.net 3.5,我有一个未知(对于当前方法)类对象数组。我知道每个类都有一个名为“Number”的属性。 我正在尝试编写一个LINQ查询,其中我正在查找具有序列中的下一个数字的对象。AKA,我在8号,使用LINQ查询来查找Number=9的对象 有人有什么建议吗 此外,我经常使用反射,因此不必担心避免使用反射。如果您确实没有可以简化为的通用类型,并且由于某种原因无法引入此类类型,则可以使用dynamic关键字。我目前没有访问编译器的权限,但是您的方法可以接受动态对象的集合并查询它们吗 例如: IEnumerab

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

有人有什么建议吗


此外,我经常使用反射,因此不必担心避免使用反射。

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

例如:

IEnumerable<dynamic> collection = ...;
var numbers = from x in collection
              select x.Number;
IEnumerable集合=。。。;
变量编号=从集合中的x开始
选择x.编号;

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

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


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

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

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

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

为了避免性能问题,您可以使用以下方法:

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[] {});
}
static void Main(字符串[]args)
{
对象[]objs=GetInitialData();
var accessor=GetGetterHelper(objs[0].GetType(),“Number”);
var res=来自objs中的a,其中访问器(a)==7选择a;
}
静态Func getterHelper(类型,字符串方法名)
{
var methodInfo=type.GetProperty(methodName).getMethod();
返回x=>(T)methodInfo.Invoke(x,新对象[]{});
}

如何知道每个对象都有一个数字属性?他们是匿名班吗?它们是否属于已知类型,您可以对其进行强制转换?它们都是同一类型的吗?它们可以是任何类的类型。但是我知道它们都有一个数字属性,虽然我已经这样设计了。如果你设计所有的类有一个数字属性,这意味着什么,但是没有在界面中捕捉到这个意思,那么你可能想考虑改变你的设计。回答您的问题最好是“所有具有数字属性的类都实现了一个公共接口,因为您是这样设计的”。我们刚刚升级到.NET 3.5,但由于购买了Visual Studio许可证,并且增加了.NET 4框架的大小,因此无法升级到.NET 4框架v4@Craig:您对框架大小有什么问题?来吧现在是2011年,没有人应该关心额外的12兆比特,这是一个次要的问题。主要问题是我们最近才购买了一些VisualStudio2008的。phoog打败了我。他发布了类似的解决方案:)。忘记了接口。。。我会调查的。也许有可能。同时我也会接受别人的想法。@phoog,你赢了我。我发布了类似的解决方案:)我有一个附带问题,我的一个类有一个名称稍有不同的属性。如何将接口的“Number”属性指向该特定类的“Index”属性?为该类指定一个仅返回Index属性的Number属性。我可能会使新属性成为显式实现。@Craig,您可以使用显式接口实现,方法是说
classmyclass:IHasNumber{int IHasNumber.Number{get{return SomeOtherProperty;}}}}
。这将使类实现IHasNumber,但仅当您将其视为IHasNumber时才会显示该属性。另外,考虑在一个单独的问题中问这个问题,这样人们就可以回答评论之外的问题:
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[] {});
}