我将对这个问题提出不同的看法。也许您只是以这些属性为例,并希望将多个属性级联。但我认为这可能是考虑所提出的继承模型的好时机。
基本上您可以使用常规继承或考虑一些设计模式,这不仅可以解决与序列化相关的问题,还可以在您的应用程序中为您提供更多“松散耦合”,使其成为更多组件模型并允许每个类只处理关心的问题,这样你就可以重复使用很多东西,让你的生活更轻松。
基于这种想法,我为您提供了一个装饰设计模式与策略设计模式混合的样本。如果我正在开发像您的示例中那样的类,我会这样做:
/// <summary>
/// The interface for validation strategy (since we are using interface, there is no need for another abstract class)
/// </summary>
public interface IValidation
{
bool IsValid { get; set; }
}
/// <summary>
/// The decorator (it dont need to be abstract) that has the serializable properties
/// </summary>
[Serializable]
public class ValidatableDecorator : IValidation
{
protected IValidation instance;
public ValidatableDecorator()
{
Init();
}
public ValidatableDecorator(IValidation instance)
{
Init();
}
protected virtual void Init() { }
public void Set(IValidation instance)
{
this.instance = instance;
}
[XmlIgnore]
public bool IsValid
{
get
{
return instance.IsValid;
}
set
{
instance.IsValid = value;
}
}
}
然后你需要实现一些具有策略模式逻辑的类,像这样:
public class BossValidatorImplementation : IValidation
{
public bool IsValid
{
get
{
return false; ;
}
set
{
throw new InvalidOperationException("I dont allow you to tell me this!");
}
}
}
public class EasyGoingValidator : IValidation
{
public bool IsValid { get; set; }
}
现在我们已经从类中分离了逻辑,我们可以从装饰器继承,选择它们对 IsValid 字段使用的策略,如下所示:
public class ChildWithBossValidation : ValidatableDecorator
{
protected ChildWithBossValidation(IValidation instance)
: this()
{
Init();
}
public ChildWithBossValidation()
: base(new BossValidatorImplementation())
{
Init();
}
protected override void Init()
{
Name = "I'm the boss!";
Sallary = 10000d;
}
public string Name { get; set; }
public double Sallary { get; set; }
}
public class ChildWithEasyGoingValidation : ValidatableDecorator
{
public ChildWithEasyGoingValidation()
: base(new EasyGoingValidator())
{
}
protected ChildWithEasyGoingValidation(IValidation instance)
: this()
{
}
protected override void Init()
{
Name = "Do as you please... :) ";
}
public string Name { get; set; }
}
这是显示该解决方案有效的代码:
public static void Main(string[] args)
{
var boos = new ChildWithBossValidation();
var coolGuy = new ChildWithEasyGoingValidation();
using (var ms = new MemoryStream())
{
var ser = new XmlSerializer(boos.GetType());
ser.Serialize(ms, boos);
string result = System.Text.Encoding.UTF8.GetString(ms.ToArray());
Console.WriteLine("With override");
Console.WriteLine(result);
}
Console.WriteLine("-------------");
using (var ms = new MemoryStream())
{
var ser = new XmlSerializer(coolGuy.GetType());
ser.Serialize(ms, coolGuy);
string result = System.Text.Encoding.UTF8.GetString(ms.ToArray());
Console.WriteLine("With override");
Console.WriteLine(result);
}
Console.ReadKey();
}
结果是:
{<?xml version="1.0"?>
<ChildWithBossValidation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>I'm the boss!</Name>
<Sallary>10000</Sallary>
</ChildWithBossValidation>-------------------<?xml version="1.0"?>
<ChildWithEasyGoingValidation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Do as you please... :) </Name>
</ChildWithEasyGoingValidation>}
所以,也许这不能回答在这种情况下如何级联属性(因为您可以通过创建自己的属性(标记以允许继承)然后将一些代码实现到 SerializeXML 来轻松地做到这一点)。这只是可以使用设计模式改进解决方案整体架构的另一种选择。但这也解决了这个特殊问题:)