gpt4 book ai didi

c# - 有没有办法在属性的属性上使用 "ShouldSerialize[PropertyName]"?

转载 作者:太空宇宙 更新时间:2023-11-03 12:49:08 26 4
gpt4 key购买 nike

我面临的问题是,当我有一个类的属性具有如下默认值时:

public class Border {
public Border() {
InitializeAdornment();
}

[DefaultValue(true)]
public bool Visible {
get;
set;
}

private void InitializeAdornment() {
Visible = true;
// Some initialization code here that don't do anything with the property...
}
}

然后将其用作具有 DesignerSerializationVisibility.Content 属性的 UserControl 的属性,如下所示:

public class Label : HitAbleControl, IText, IBorder {
public Label() {
InitializeAdornments();
}

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Border Border {
get {
return __border;
}
set {
__border = value;
}
}

private Border __border;

private void InitializeAdornments() {
Border = new Border {
Visible = false
};
// Some initialization code here that don't do anything with the property...
}
}

如果我使用 Visual Studio Designer 设置 label1.Border.Visible = true,它不会被序列化,但在这种情况下它的默认值应该是 false 而不是 true。

我知道我可以将 Border 类更改为始终序列化,或者检查默认值应该是 true 还是 false,但我想知道是否有类似 ShouldSerialize[PropertyName] 到属性的属性或此序列化问题的其他解决方法,而不更改序列化器。

我搜索了几个小时试图解决这个问题,但没有求助于 CodeDomSerializer,或者至少理解了为什么 visual studio 设计师不序列化它。

任何帮助将不胜感激,谢谢!

最佳答案

首先让我声明没有ShouldSerialize[PropertyName] 或其他标准机制来控制嵌套对象属性的行为。

您所要求的可以完成,但需要在包含的类中有一些额外的状态。如果您不提供公共(public) setter ,它可能会更简单,因此您可以传递某种所有者接口(interface)或从 Border 类调用的东西。由于这似乎不是一个选项,因此它需要一些额外的工作,如在 setter 中克隆传递的值。

关键是要有一个默认值作为类属性,而不是静态常量。请注意,无论您是通过设计器还是代码设置值,序列化程序都使用 DefaultValueAttribute 来确定该值是否需要序列化。顺便说一句,最简单的方法可能是删除该属性,添加一个名为 ShouldSerializeVisiblebool 方法并始终返回 true。这是一个更高级的实现:

[TypeConverter(typeof(ExpandableObjectConverter))]
public class Border
{
public Border()
{
InitializeAdornment();
}

public Border Clone() { return (Border)MemberwiseClone(); }

public bool Visible { get; set; }

private bool ShouldSerializeVisible() { return Visible != DefaultVisible; }
private void ResetVisible() { Visible = DefaultVisible; }

[Browsable(false)]
[RefreshProperties(RefreshProperties.All)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool DefaultVisible { get; set; }

private void InitializeAdornment()
{
Visible = DefaultVisible = true;
// Some initialization code here that don't do anything with the property...
}
}

请注意 DefaultValueAttribute 已删除并替换为私有(private) ShouldSerialize[PropertyName]Reset[PropertyName] 方法以及 DefaultVisible 实例成员。

Label 类中的属性将是:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Border Border
{
get { return __border; }
set
{
if (value != null)
{
value = value.Clone();
value.DefaultVisible = false;
}
__border = value;
}
}

缺点是传递的 Border 实例必须在 setter 中克隆。

关于c# - 有没有办法在属性的属性上使用 "ShouldSerialize[PropertyName]"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36280489/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com