Tôi sẽ cung cấp một cái nhìn khác về câu hỏi này. Có lẽ bạn chỉ sử dụng các thuộc tính đó làm ví dụ và muốn có các thuộc tính severall được xếp tầng. Nhưng tôi nghĩ rằng đây có thể là thời điểm tốt để suy nghĩ về mô hình kế thừa được đề xuất. Một cách cơ bản, bạn có thể sử dụng kế thừa thường xuyên hoặc suy nghĩ về một số mẫu thiết kế, có thể không giải quyết vấn đề liên quan đến serialization, nhưng có thể cung cấp cho bạn một số "khớp nối lỏng lẻo" trong ứng dụng của bạn, làm cho nó thành một mô hình thành phần hơn và allowwing mỗi lớp để đối phó chỉ với những gì là mối quan tâm, bằng cách này bạn có thể tái sử dụng rất nhiều thứ và làm cho cuộc sống của bạn dễ dàng hơn.
Dựa trên suy nghĩ đó, im cung cấp cho bạn mẫu của Mẫu thiết kế trang trí được trộn lẫn với Mẫu thiết kế chiến lược. Nếu được phát triển các lớp học như những người trên mẫu của bạn, đây là làm thế nào tôi sẽ làm điều đó:
/// <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;
}
}
}
Sau đó, bạn cần phải thực hiện một số lớp học có logic của mẫu chiến lược, như thế này:
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; }
}
Bây giờ chúng ta có logic tách ra khỏi lớp học, chúng ta có thể kế thừa từ các trang trí, lựa chọn chiến lược mà họ sử dụng để lĩnh vực IsValid, như thế này:
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; }
}
Đây là mã t o cho thấy các giải pháp hoạt động:
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();
}
Kết quả là:
{<?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>}
Vì vậy, có lẽ đây không trả lời như thế nào để thác các thuộc tính trong trường hợp này (vì bạn có thể dễ dàng làm điều đó bằng cách tạo của bạn thuộc tính riêng (đánh dấu để cho phép thừa kế) và sau đó triển khai một số mã vào SerializeXML). Đây chỉ là một tùy chọn khác có thể cải thiện kiến trúc tổng thể của các giải pháp bằng cách sử dụng Pattern Design.Nhưng điều này giải quyết vấn đề cụ thể này cũng :)
Nếu 'XmlIgnoreAttribute' đã được khai báo bằng' Inherited = true', điều này sẽ hoạt động. Than ôi, nó không phải là, và đây không phải là một cách để làm cho nó hoạt động: http://ideone.com/B0KASa '[AttributeUsageAttribute (AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = true) ] lớp công khai XmlInheritIgnoreAttribute: System.Xml.Serialization.XmlIgnoreAttribute { } ' –
@TimS. Tôi đã thử mã của bạn và như bạn đã đề xuất đúng, nó không hoạt động trong tình huống này có lẽ bởi vì nó không được thiết kế cho điều này? – Abhinav
@abhinav Đủ công bằng, không nhận ra. –