2

I have a list of anonymous objects as:

var jobs = new List<object>
               {
                 new
                 {
                   JobName = "Job1",
                   JobDate = "Date1",
                   JobUser = "User1"
                 },
                 new
                 {
                   JobName = "Job2",
                   JobDate = "Date2",
                   JobUser = "User2"
                 }
               };

how can I find the "Job2" using linq?

e.g.

var job2 = jobs.Where(x=>x.JobName == "Job2");

I am aware of the below but cannot apply it to my use case above in an elegant way:

var anonymJob = new 
                {
                  JobName = "Job2",
                  JobDate = "Date2",
                  JobUser = "User2"
                };

dynamic tJob = anonymJob.GetType();
string jobName = tJob.JobName; // this will be "Job2"

Please note jobs.First() or Last() are not accepted as correct answers to this question is how to find a job based on its specific properties.

Thanks

MaYaN
  • 6,683
  • 12
  • 57
  • 109

4 Answers4

9

If you're working within the same method, you can just use a list of the anonymous type:

var jobs = new [] {
    new { JobName = "Job1", JobDate = "Date1", JobUser = "User1" },
    new { JobName = "Job2", JobDate = "Date2", JobUser = "User2" }
}.ToList();

var job2 = jobs.First(x => x.JobName == "Job2");

The use of the implicitly typed array allows your list to still be strongly typed, but using the anonymous type.

If you must use a List<object>, then I'd expect:

IEnumerable<dynamic> dynamicJobs = jobs;
var job2 = dynamicJobs.First(x => x.JobName == "Job2");

to work. Note that this doesn't involve copying the list or changing the declaration type of the list at all. You could also use:

var job2 = jobs.Cast<dynamic>().First(x => x.JobName == "Job2");
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • @MaYaN: My answer doesn't say anything about knowing where the job is within the list. It just finds the first job matching the predicate. If you want to find *multiple* matches, use `Where` instead of `First`. – Jon Skeet May 13 '13 at 14:01
  • @MaYaN: Be aware that the solution using `dynamic` really *is* dynamic - so if you have typo in `JobName`, the compiler won't find it for you. That's similar to the second part of my answer, but the version using a strongly typed list with the anonymous type is preferable IMO, if you're going to search within the same method. – Jon Skeet May 13 '13 at 14:20
4

You can use dynamic in your query:

var job2 = jobs.Where(x => ((dynamic)x).JobName == "Job2");
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
2

Make it a List<dynamic> instead of List<object>.

Then you can use the normal LINQ queries.

Dirk
  • 10,668
  • 2
  • 35
  • 49
  • @MaYaN This is unlikely to be the actual solution you want to rely on. You're breaking all static typing and compile time checking by using this solution. Anonymous objects were designed to be used in conjunction with methods of type inference such that you can maintain compile time validation of your program, as is shown in Jon's answer. – Servy May 13 '13 at 14:21
  • @Servy I agree with you. It was more of a quick fix to make it work. – Dirk May 13 '13 at 14:22
  • @Dirk If you know that it's an inappropriate solution to the problem, and that there is a much more appropriate and advisable solution to the problem, then why did you post this one. Clearly the OP isn't capable of realizing that it's not a good solution, or what the appropriate solution is, so posting this is completely irresponsible. – Servy May 13 '13 at 14:27
  • 1
    It is hardly inappropriate, it is just not the best solution and I didn't think of anonymous arrays when I posted it. – Dirk May 13 '13 at 14:32
1

Use List<dynamic> instead of List<object>.

Paste this in to LINQPad to see:

var jobs = new List<dynamic>
               {
                 new
                 {
                   JobName = "Job1",
                   JobDate = "Date1",
                   JobUser = "User1"
                 },
                 new
                 {
                   JobName = "Job2",
                   JobDate = "Date2",
                   JobUser = "User2"
                 }
               };

jobs.Where(x=>x.JobName == "Job2").Dump();
Moo-Juice
  • 38,257
  • 10
  • 78
  • 128