可以使用类的成员函数更改对象的实例吗?

Posted

技术标签:

【中文标题】可以使用类的成员函数更改对象的实例吗?【英文标题】:Can one change the instance of an object with the member function of its class? 【发布时间】:2019-01-21 13:06:33 【问题描述】:

一个成员函数应该改变调用对象的实例。但我最近的尝试并没有改变实例。

我想提供一个基类,它实现了一个将字符串(或文件)反序列化为子类对象的函数。

我试图实现一个扩展方法,但它没有按预期工作。调用实例不会改变。 类子类:基类 [XmlAttribute(AttributeName = "属性")] 公共字符串属性集;得到; 类基类 类静态 BaseClassExtension public static void Deserialize(this BaseClass bar, string filePath) 使用 (StreamReader reader = new StreamReader(filePath)) XmlSerializer 序列化器 = new XmlSerializer(obj.GetType()); bar = (BaseClass)serializer.Deserialize(reader); 课堂节目 公共无效主要() ChildClass foo = new ChildClass(); foo.Deserialize("file.xml") 在 foo.Deserialize() 中,对象“bar”被填充,但函数结束后,foo 仍然是“空”的 new ChildClass(),并且没有 bar 的内容。

这样的事情有可能吗?

编辑: 好的,让我们忘记扩展方法。另一种尝试是:

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

我“需要”的东西是这样的:

class BaseClass

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

或者我可以使用构造函数吗?

最好的问候, 马丁

【问题讨论】:

即使这段代码有效,也很难理解。你的扩展方法应该返回一个BaseClass,它不应该使用传入的参数。 DeserializeNOT 成员函数。它是一种扩展方法,不会返回它反序列化的对象。它使用bar,就好像它是一个临时变量 你这里的设置是错误的。你的成员函数不应该接受一个参数,应该按照 this = new ChildClass(stuff); 的方式做一些事情。然后在课堂之外,如果需要,您可以将其转换为子类 你正在寻找这个,它还没有实现。 github.com/dotnet/roslyn/issues/165 @PanagiotisKanavos 你是对的。最初我试图实现一个成员函数,但在我的尝试中我使用了扩展方法。我的错。 【参考方案1】:

这是不可能的。在您的情况下,“bar”是静态方法范围内的局部变量,最终您将其重新分配给不同的实例。您处理的不是同一个调用对象。

根据您尝试解决的解决方案,您可以将基类/子类分成两个单独的类,并在“子”中拥有一个“基”类型的成员。

【讨论】:

【参考方案2】:

我认为不可能从内部更改实例化对象。但是,您可以将初始化代码作为基类的一部分放入静态方法中,该方法显式返回可以分配给新变量的对象的新实例。这样,您只需通过该方法实例化您的类一次。

基本上你会这样做:

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

这比从自身调用的方法重新分配 foo 更干净。然后您的 BaseClass 将具有:

public static BaseClass Deserialize(String filePath)  ... 

【讨论】:

那我就不能从 BaseClass 派生我的 ChildClass 了吧? 你是对的。我的逻辑倒退了。 BaseClass 实现需要是虚拟的,并且您的子类将覆盖它以返回正确的对象。因此,这种方法与使用一系列辅助方法来创建派生类没有什么不同。

以上是关于可以使用类的成员函数更改对象的实例吗?的主要内容,如果未能解决你的问题,请参考以下文章

第24课经典问题解析(下)--------类的成员函数和成员变量隶属某个具体对象吗

面向对象

类与类之间的友元关系可以继承吗? 友元函数是类的成员函数吗?

Java类的实例化对象成员在内存空间怎么分配,调用构造函数又是在内存中怎么分配

MFC中静态成员函数调用其他类的非静态变量

C++中的派生类,可以不定义对象直接调用基类的成员和调用自己的成员函数嘛???