可以使用类的成员函数更改对象的实例吗?
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
,它不应该使用传入的参数。
Deserialize
是 NOT 成员函数。它是一种扩展方法,不会返回它反序列化的对象。它使用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课经典问题解析(下)--------类的成员函数和成员变量隶属某个具体对象吗
类与类之间的友元关系可以继承吗? 友元函数是类的成员函数吗?