2

What I have now is the following code:

Tutorial tutorial =
  (from tutorial in xmlDoc.Descendants("Tutorial")
   select new Tutorial
   {
     Author = tutorial.Element("Author").Value,
     Title = tutorial.Element("Title").Value,
     Date = DateTime.Parse(tutorial.Element("Date").Value),
   }).First();

myTutorial.Author = tutorial.Author;
myTutorial.Title = tutorial.Title;
myTutorial.Date = tutorial.Date;

myTutorial is passed from another method. And the code below has to 'fill' it.

The question is: Is there a way to create a LINQ query, which will assign values to the properties of an existing object, rather that creating a new one.

I would like my code to look something like this:

   Tutorial tutorial =
  (from tutorial in xmlDoc.Descendants("Tutorial")
   select myTutorial
   {
     Author = tutorial.Element("Author").Value,
     Title = tutorial.Element("Title").Value,
     Date = DateTime.Parse(tutorial.Element("Date").Value),
   });

The problem I have is: I have an object which initially only has half of it's properties set, later I need to fill the rest of the properties. This needs to be done asynchronously.

My Approach: I use WebClient's asynchronous method DownloadStringAsync to download XML file. In the event handler I wan't to fill an object with the properties it misses. And that's why I would like to directly pass values to my object rather than creating a new one.

Please let me know if it is not the best approach.

3
  • 2
    Are you sure the 1st example even compiles? I think you need a .First() in there. Commented Dec 9, 2010 at 11:41
  • yea right! I have just typed the code here, so I missed the .First(). Commented Dec 9, 2010 at 11:44
  • 1
    btw, you might want to note the use of cast rather than .Value in the answer I give; in addition to using the correct xml formats (i.e. xml dates aren't the same as DateTime.Parse) this reacts appropriately if elements are missing - for example casting to (DateTime?) will return a null if the element is missing, rather than the .Value being a null-ref exception. Commented Dec 9, 2010 at 11:54

3 Answers 3

1

OK, this is pure evil:

var dropThis =
  (from tutorial in xmlDoc.Descendants("Tutorial")
   select new
   {
     Author = (myTutorial.Author = (string)tutorial.Element("Author")),
     Title = (myTutorial.Title = (string)tutorial.Element("Title")),
     Date = (myTutorial.Date = (DateTime)tutorial.Element("Date")),
   }).First();
Sign up to request clarification or add additional context in comments.

2 Comments

Yea this should work. But looks quite evil :) So as I far as I can understand, you have to create an object if you are parsing XML using LINQ.
Well, sort of; you need to satisfy a projection. There are other things you could do instead of new - but assigning 3 props is the trick.
0

LINQ functional queries are actually designed in such way, that they shouldn't modify existing objects or collections, i.e. preserve state (although there are ways (hacks?) to do so).

But you can pretty easily implement reflection-based method to achieve what you want.

Comments

0

I noticed this question and felt the need to add another dirty solution. How about Extension methods?

public static void AddTo(this IEnumerable<Tutorial> source, Tutorial projection)
{
    if (source.Count() == 0)
        return;

    projection.Title = source.First().Title;
    projection.Author = source.First().Author;
    projection.Date = source.First().Date;
}

Now you can just call it to add to your current tutorial. Also, I recommend using (string) instead of .Value so you avoid null reference exceptions.

tutorialXml
    .Descendants("Tutorial")
    .Select(tutorial => new Tutorial
         {
             Author = (string) tutorial.Element("Author"),
             Title = (string) tutorial.Element("Title"),
             Date = DateTime.Parse((string) tutorial.Element("Date")),
         })
    .AddTo(myTutorial);

Anyway, Good luck. Just wanted to add a dirty solution to this ball of mud.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.