10

Ok, I'm probably just having an epic fail here, but my mind wants to say this should work.

Assume DataProtect.DecryptData takes an encrypted string as input and a decrypted string as output. Assume deserializeXML makes the appropriate object and returns it from the newly decrypted string.

So. Why wouldn't this work?

class ArrivedDetails
{
///...

    internal ArrivedDetails(string encrypted)
    {
        this = DataProtect.deserializeXML(DataProtect.DecryptData(encrypted));
    }
///...

Gives me an error of

Cannot assign to '<this>' because it's read only

More specifically,, how can I get this working? I essentially want to decrypt an XML serialized version of the object and then deserialize it within the constructor.

I'm open to "you can't" (with an explanation) as I can put it elsewhere and just assign values, but my mind says something like this should be possible.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
dotalchemy
  • 2,459
  • 19
  • 24

4 Answers4

18

No, this is not possible using a constructor, you can't reassign this.

Use a static method instead:

public static ArrivedDetails CreateFromString(string encrypted)
{
    return DataProtect.deserializeXML(DataProtect.DecryptData(encrypted));
}

Call it:

ArrivedDetails details = ArrivedDetails.CreateFromString(encrypted);
empty
  • 5,194
  • 3
  • 32
  • 58
Femaref
  • 60,705
  • 7
  • 138
  • 176
  • 1
    Though I would agree with dotalchemy that the original concept should work, a static method does the trick. I like that you are not instantiating a new object and just returning it. – Farhan Jul 24 '12 at 18:48
  • This does not deserialize to , does it? – Erik Jan 18 '21 at 11:04
7

You can archive this with reflection as follows.

var tmp = DataProtect.deserializeXML(DataProtect.DecryptData(encrypted));
foreach (var property in GetType().GetProperties())
    if (property.GetCustomAttributes(typeof (XmlIgnoreAttribute), false).GetLength(0) == 0)
        property.SetValue(this, property.GetValue(tmp, null), null);

This assigns the deserialized object to a temporal variable, and copy the value in each public property to this with reflection. This snippet avoids to copy properties with the XmlIgnore attribute.

Goodies
  • 1,951
  • 21
  • 26
fujieda
  • 91
  • 1
  • 4
3

You can not assign anything to "this". Change ArriveDetails to a static that return the deserialised object.

class ArrivedDetails
{
    static ArrivedDetails Create(string encrypted)
    { return DataProtect.deserializeXML(...) }
}
Richard Schneider
  • 34,944
  • 9
  • 57
  • 73
2

What you want is a static factory method that creates the object you require.

class ArrivedDetails
{
///...

    public static ArrivedDetails CreateFromEncryptedKey(string encrypted)
    {
        return DataProtect.deserializeXML(DataProtect.DecryptData(encrypted));
    }
///...

The reason your initial approach didn't work is because this is a private read-only instance field that returns the object from which it is called. You can't write to this.

Martin Doms
  • 8,598
  • 11
  • 43
  • 60