使用 LINQ 解析 XML 并填充现有对象的属性,而不是创建新的属性

发布于 2024-10-06 15:40:33 字数 1099 浏览 5 评论 0原文

我现在拥有的是以下代码:

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 是从另一个方法传递的。下面的代码必须“填充”它。

问题是:有没有一种方法可以创建 LINQ 查询,它将值分配给现有对象的属性,而不是创建一个新对象。

我希望我的代码看起来像这样:

   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),
   });

我遇到的问题是: 我有一个对象,最初只设置了一半的属性,后来我需要填充其余的属性。这需要异步完成。

我的方法: 我使用 WebClient 的异步方法 DownloadStringAsync 来下载 XML 文件。在事件处理程序中,我不想用对象缺少的属性来填充对象。这就是为什么我想直接将值传递给我的对象而不是创建一个新对象。

如果这不是最好的方法,请告诉我。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千鲤 2024-10-13 15:40:33

好吧,这纯粹是邪恶的:

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();

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();
画尸师 2024-10-13 15:40:33

LINQ 函数查询实际上是以这样的方式设计的,即它们不应该修改现有对象或集合,即保留状态(尽管有一些方法(黑客?)可以这样做)。

但是您可以很容易地实现基于反射的方法来实现您想要的。

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.

分开我的手 2024-10-13 15:40:33

我注意到这个问题并觉得有必要添加另一个肮脏的解决方案。扩展方法怎么样?

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;
}

现在您可以调用它来添加到您当前的教程中。另外,我建议使用 (string) 而不是 .Value,这样可以避免空引用异常。

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);

不管怎样,祝你好运。只是想给这个泥球添加一种肮脏的解决方案。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文