0
votes

A member function should change the instance of the calling object. But my recent attempts didn't change the instance.

I want to provide a base class, which implements a function to deserialize a string (or file) to an object of the child class.

I tried to implement an extension method, but it doesn't work as expected. The calling instance doesn't change. class ChildClass : BaseClass { [XmlAttribute(AttributeName = "attribute")] public string Atribute { set; get; } } class BaseClass {} class static BaseClassExtension { public static void Deserialize(this BaseClass bar, string filePath) { using (StreamReader reader = new StreamReader(filePath)) { XmlSerializer serializer = new XmlSerializer(obj.GetType()); bar = (BaseClass)serializer.Deserialize(reader); } } } class Program { public void Main() { ChildClass foo = new ChildClass(); foo.Deserialize("file.xml") } } Within foo.Deserialize() the object "bar" is filled, but after the function ends, foo is still the "empty" new ChildClass() and does not have the content of bar.

Is it even possible to do such thing?

EDIT: Ok lets forget the extension method. Another attempt was:

class ChildClass : BaseClass
{
    [XmlAttribute(AttributeName = "atribute")]
    public string Atribute { set; get; }
}

class BaseClass
{
    public void Deserialize(string filePath)
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            return (BaseClass)serializer.Deserialize(reader);
        }
    }
}

class Program
{
    public void Main()
    {
        ChildClass foo = new ChildClass();

        // looks pretty bad and seems quite inconvenient to me 
        foo = (ChildClass)foo.Deserialize("file.xml")
    }
}

What I "need" is something like:

class BaseClass
{
    public void Deserialize(string filePath)
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            this = (BaseClass)serializer.Deserialize(reader);
        }
    }
}

Or can I use the constructor?

Best regards, Martin

2
Even if this code worked, it would be hard to understand. Your extension method should return a BaseClass, it shouldn't use the parameter passed in.DavidG
Deserialize is NOT a member function. It's an extension method doesn't that return the object it deserializes. It uses bar as if it were a temporary variablePanagiotis Kanavos
Your setup here is wrong. Your member function shouldn't take in a param and should do something along the lines of this = new ChildClass(stuff); Then outside the class you can cast it to a child class if neededProdigle
You're looking for this, which isn't implemented yet. github.com/dotnet/roslyn/issues/165ColinM
@PanagiotisKanavos You are right. Initially I was trying to implement a memberfunction, but in my attempts I used a extension method then. My bad.HarryKane

2 Answers

0
votes

It is not possible with how this is structured. In your case, 'bar' is a local variable within the scope of the static method that, toward the end, you reassign to a different instance. You're not dealing with the same calling object.

Depending on the solution you're attempting to solve for, you could break the base/child classes apart into two separate classes, and have a member of type 'base' within 'child.'

0
votes

I don't think it's possible to change the instantiated object from within itself. You can, however, put your initialization code into a static method as part of your base class, that explicitly return a new instance of the object that you can assign to a new variable. That way you are only instantiating your class once through the method.

basically you would be doing:

foo = (ChildClass)BaseClass.Deserialize("file.xml");

which would be a bit cleaner than reassigning foo from a method called from itself. Your BaseClass would then have:

public static BaseClass Deserialize(String filePath) { ... }