LINQ-запрос на объект с неизвестным классом - PullRequest
4 голосов
/ 13 мая 2011

У меня есть массив неизвестных (текущему методу) объектов класса.Я знаю, что у каждого класса есть свойство под названием «Число».Я пытаюсь написать запрос LINQ, где я ищу объект со следующим номером в последовательности.АКА, я под номером 8, использую запрос LINQ, чтобы найти объект, где номер = 9.

Кто-нибудь получил предложение?

Кроме того, я часто использую отражение, поэтому не беспокойтесь, избегая его.

Ответы [ 5 ]

3 голосов
/ 13 мая 2011

Если все объекты наследуются от известного интерфейса, вы можете привести их, например,

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> для начала, и вам даже не придется разыгрывать.

3 голосов
/ 13 мая 2011

Вы можете создать интерфейс - INumber со свойством Number. Каждый из объектов, которые вы имеете в массиве, может реализовать этот интерфейс.

Таким образом, у вас будет массив известного типа INumber. Таким образом, ваш запрос будет легко отлаживать и обслуживать.

1 голос
/ 13 мая 2011

Чтобы избежать проблем с производительностью, вы можете использовать следующий метод:

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[] {});
}
1 голос
/ 13 мая 2011

Если, как вы указали в другом месте, вы спроектировали все классы, вы могли бы поместить это свойство числа во входной интерфейс и сделать так, чтобы все классы реализовали этот интерфейс.Затем в запросе linq используйте интерфейс.

1 голос
/ 13 мая 2011

Если у вас действительно нет общего типа, который можно сократить, и по какой-то причине вы не можете ввести такой тип, то вы можете использовать ключевое слово dynamic. В данный момент у меня нет доступа к компилятору, но может ли ваш метод принять коллекцию динамических объектов и запросить их?

Например:

IEnumerable<dynamic> collection = ...;
var numbers = from x in collection
              select x.Number;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...