反序列化和构造函数关系
deserialize and constructor relationship
我不知道为什么我不能在网上找到一个简单的快速查找,但我想知道反序列化一个对象的 XML 表示和它的构造函数之间的关系是什么目的?
我假设它使用默认构造函数。如果是这种情况,它将 运行 构造函数中的代码,但之后不会更新对象本身以反映 XML?
这里有更多关于我的意思的上下文...
我有一个对象,它有两个实际上也是对象的属性:
public class Deployment
{
public AppPoolSettings AppPool { get; set; }
public WebSiteSettings Site { get; set; }
public Deployment()
{
//the object constructors below init their internal properties as well...
this.AppPool = new AppPoolSettings();
this.Site = new WebSiteSettings();
}
}
我目前遇到的问题是,在 XML 中,AppPool
属性 可以为空(例如,如果您仅部署 HTML包裹)。序列化程序正常工作,也就是说,生成的 XML 仅包含 Site 的条目,而没有 AppPool 的条目。
然而,当我反序列化那个 XML 时,我的 Deployment
对象的 AppPool 属性 总是被实例化和初始化......这不是 XML在说。
是我做错了什么还是真的只是因为默认构造函数?
看吧,我希望反序列化器按以下顺序执行任务:
1-调用默认构造函数
2- AppPool 属性 是否存在于 XML 中?
是 --> 填写,
否 --> 设置为 NULL
3- 站点 属性 是否存在于 XML 中?
是 --> 填写,
否 --> 设置为 NULL
为什么不这样做?
我相信正确答案是:是的,对空属性的违反直觉的处理(在序列化数据中省略它们并且在反序列化时不对它们进行任何处理)是 XmlSerializer
.但是您可以覆盖该行为并强制 XmlSerializer 将空值写入 XML 并具有如下属性:
public class Deployment
{
[XmlElement(IsNullable = true)]
public AppPoolSettings AppPool { get; set; }
[XmlElement(IsNullable = true)]
public WebSiteSettings Site { get; set; }
public Deployment()
{
//the object constructors below init their internal properties as well...
this.AppPool = new AppPoolSettings();
this.Site = new WebSiteSettings();
}
}
然后您将在 XML 中得到 <AppPool xsi:nil="true" />
和预期的反序列化。
调用了默认构造函数,因此分配了 Site 和 AppPool。如果你想让它们成为 null
也许你可以试试这个代码:
public class Deployment
{
private AppPoolSettings appPool;
public AppPoolSettings AppPool
{
get { return appPool; }
set
{
// if (appPool == null)
// appPool = new AppPoolSettings();
appPool = value;
}
}
private WebSiteSettings site;
public WebSiteSettings Site
{
get { return site; }
set
{
// if (site == null)
// site = new WebSiteSettings();
site = value;
}
}
public Deployment()
{
// No instatiation anymore...
}
}
你的期望是错误的。 XmlSerializer
将构造对象(通过调用无参数构造函数,如果有 none - 抛出异常)。然后属性将使用一些反射魔法一一填充。
那么会发生什么:
构造函数被调用,在其中设置 AppPool
和 Site
的值。
xml中有Site
属性,反序列化赋值
但是xml中没有AppPool
,所以没有任何变化,它的值保持不变(不是null
)。
要让 null
对应 AppPool
,您不应该在构造函数中设置它的值。如果在 xml.
中丢失,它将保持这样
这是一种可能的解决方案:
public class Deployment
{
public AppPoolSettings AppPool { get; set; }
public WebSiteSettings Site { get; set; }
// used by deserializer
public Deployment() { }
// use this to construct object
public static Deployment Create()
{
return new Deployment()
{
AppPool = new AppPoolSettings(),
Site = new WebSiteSettings()
};
}
}
我不知道为什么我不能在网上找到一个简单的快速查找,但我想知道反序列化一个对象的 XML 表示和它的构造函数之间的关系是什么目的?
我假设它使用默认构造函数。如果是这种情况,它将 运行 构造函数中的代码,但之后不会更新对象本身以反映 XML?
这里有更多关于我的意思的上下文...
我有一个对象,它有两个实际上也是对象的属性:
public class Deployment
{
public AppPoolSettings AppPool { get; set; }
public WebSiteSettings Site { get; set; }
public Deployment()
{
//the object constructors below init their internal properties as well...
this.AppPool = new AppPoolSettings();
this.Site = new WebSiteSettings();
}
}
我目前遇到的问题是,在 XML 中,AppPool
属性 可以为空(例如,如果您仅部署 HTML包裹)。序列化程序正常工作,也就是说,生成的 XML 仅包含 Site 的条目,而没有 AppPool 的条目。
然而,当我反序列化那个 XML 时,我的 Deployment
对象的 AppPool 属性 总是被实例化和初始化......这不是 XML在说。
是我做错了什么还是真的只是因为默认构造函数?
看吧,我希望反序列化器按以下顺序执行任务:
1-调用默认构造函数
2- AppPool 属性 是否存在于 XML 中?
是 --> 填写,
否 --> 设置为 NULL
3- 站点 属性 是否存在于 XML 中?
是 --> 填写,
否 --> 设置为 NULL
为什么不这样做?
我相信正确答案是:是的,对空属性的违反直觉的处理(在序列化数据中省略它们并且在反序列化时不对它们进行任何处理)是 XmlSerializer
.但是您可以覆盖该行为并强制 XmlSerializer 将空值写入 XML 并具有如下属性:
public class Deployment
{
[XmlElement(IsNullable = true)]
public AppPoolSettings AppPool { get; set; }
[XmlElement(IsNullable = true)]
public WebSiteSettings Site { get; set; }
public Deployment()
{
//the object constructors below init their internal properties as well...
this.AppPool = new AppPoolSettings();
this.Site = new WebSiteSettings();
}
}
然后您将在 XML 中得到 <AppPool xsi:nil="true" />
和预期的反序列化。
调用了默认构造函数,因此分配了 Site 和 AppPool。如果你想让它们成为 null
也许你可以试试这个代码:
public class Deployment
{
private AppPoolSettings appPool;
public AppPoolSettings AppPool
{
get { return appPool; }
set
{
// if (appPool == null)
// appPool = new AppPoolSettings();
appPool = value;
}
}
private WebSiteSettings site;
public WebSiteSettings Site
{
get { return site; }
set
{
// if (site == null)
// site = new WebSiteSettings();
site = value;
}
}
public Deployment()
{
// No instatiation anymore...
}
}
你的期望是错误的。 XmlSerializer
将构造对象(通过调用无参数构造函数,如果有 none - 抛出异常)。然后属性将使用一些反射魔法一一填充。
那么会发生什么:
构造函数被调用,在其中设置
AppPool
和Site
的值。xml中有
Site
属性,反序列化赋值但是xml中没有
AppPool
,所以没有任何变化,它的值保持不变(不是null
)。
要让 null
对应 AppPool
,您不应该在构造函数中设置它的值。如果在 xml.
这是一种可能的解决方案:
public class Deployment
{
public AppPoolSettings AppPool { get; set; }
public WebSiteSettings Site { get; set; }
// used by deserializer
public Deployment() { }
// use this to construct object
public static Deployment Create()
{
return new Deployment()
{
AppPool = new AppPoolSettings(),
Site = new WebSiteSettings()
};
}
}