2

I have found some threads about this problem, like this and this but I cannot figure out how I could implement this for my code.

I have something like this:

public sealed class Party
{
    public Party()
    {
        load();
    }
    ....
    public async void Load()
    {
       string fileName = this.Name + ".xml";
       var files = ApplicationData.Current.LocalFolder.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByName).GetResults();
        var file = files.FirstOrDefault(f => f.Name == fileName);
        if (file != null)
        {
            using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(fileName))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Party));
                Party data = (Party)serializer.Deserialize(stream);
                this = data;
            }
        }
    }
}

This throws me the "cannot assign to ' this ' because it is read-only". Since I read a file and I need to await it, it have to be async, and then I cannot have the class as a return type.

Any ideas for how to deserialize this to itself?

Community
  • 1
  • 1
gubbfett
  • 2,157
  • 6
  • 32
  • 54
  • Why not treat that method as a factory method to produce instances of `Party`? – 48klocs Jan 20 '15 at 21:19
  • @48klocs factory methods is something new to me. wanna fill in with an example, or do you just recommend google? :) – gubbfett Jan 20 '15 at 21:24
  • Here's my upvote to remove that ugly '-1'. This is a very important question regardless of its impossibility. – Glitch Sep 03 '17 at 20:45

1 Answers1

3

You can't assign to this. It's an instance of an object, and it makes no sense to change it.

Either have a static method that returns the Party (and use that to create the class):

public static Party Load()
{
    // ... Deserialize
    return (Party)serializer.Deserialize(stream);
}

Or load the information into your class using the deserialized object (which would be inefficient, since they're the same type):

public void Load()
{
    // ... Deserialize
    Party data = (Party)serializer.Deserialize(stream);
    this.Name = data.Name;
    this.PartyInfo = data.PartyInfo;
} 

Clearly, the static method should be preferred here, and is considered the factory pattern.

Will Eddins
  • 13,628
  • 5
  • 51
  • 85
  • now i feel really stupid. since the "party" actually only have a name and a list, your second option is brilliant in it's simplicity. why do you find it inefficient? – gubbfett Jan 20 '15 at 21:23
  • @gubbfett Because you already have the party object, if you copy all the data, now you have 2 copies of it, and the first will be garbage collected. If you use the static method, you're just changing how you use it from `Party party = new Party()` to `Party party = Party.Load()` and now it's using half the memory. – Will Eddins Jan 20 '15 at 21:24
  • ah. ok. in your first example, do you want to explain the deserialization? since i read from file, i have just found async methods. usig async i can only have void or task. should i have the stream as some kin of global or something? – gubbfett Jan 20 '15 at 21:28
  • @gubbfett Return `Task` and make sure you use it like the following: `Party party = await Party.Load()`. You'll probably want to rename the method to `LoadAsync()` while you're at it, so it's obvious that its an async method. The rest of your Load code stays the same, just change the last line to `return data;` – Will Eddins Jan 20 '15 at 21:29