私はこの質問について別の見方をします。これらのプロパティを例として使用しただけで、複数のプロパティをカスケードしたいと思うかもしれません。しかし、これは、提案された継承モデルについて考える良い機会かもしれないと思います。
基本的に、通常の継承を使用するか、シリアライゼーションに関連する問題を解決するだけでなく、アプリケーションで「疎結合」を提供して、より多くのコンポーネントモデルにし、各クラスを許可するいくつかのデザインパターンについて考えることができます関心のあるものだけに対処することで、多くのものを再利用して生活を楽にすることができます。
その考えに基づいて、Decorator デザイン パターンと Strategy デザイン パターンを組み合わせたサンプルを提供します。あなたのサンプルのようなクラスを開発していた場合、これは私がそれを行う方法です:
/// <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 にコードを実装することで簡単に実行できるため)。これは、デザイン パターンを使用してソリューションの全体的なアーキテクチャを改善できるもう 1 つのオプションです。しかし、これはこの特定の問題も解決します:)