我有一个未知(对于当前方法)类对象的数组。我知道每个类都有一个名为“Number”的属性。 我正在尝试编写一个LINQ查询,我正在寻找具有下一个Number序列的对象。 AKA,我在第8位,使用LINQ查询来查找Number = 9的对象。
有人有建议吗?
另外,我经常使用反射,所以不要担心避免它。
答案 0 :(得分:3)
您可以创建一个接口 - 带有属性Number的INumber。您在阵列中拥有的每个对象都可以实现此接口。
这样,您将拥有一个已知类型为INumber的数组。这样,您的查询将易于调试和维护。
答案 1 :(得分:3)
如果对象都是从已知接口继承的,则可以转换它们,例如
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>
开始,您甚至不需要施放。
答案 2 :(得分:1)
如果您真的没有可以减少的常见类型并且由于某种原因无法引入这样的类型,那么您可以使用dynamic关键字。我目前无法访问编译器,但您的方法是否可以接受动态对象的集合并进行查询?
例如:
IEnumerable<dynamic> collection = ...;
var numbers = from x in collection
select x.Number;
答案 3 :(得分:1)
如果您在其他地方指出您设计了所有类,则可以将该数字属性放在in接口中,并让所有类实现该接口。然后,在linq查询中,使用接口。
答案 4 :(得分:1)
为避免性能问题,您可以使用以下方法:
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[] {});
}