根据 Microsoft的建议,最好的做法是密封所有.Net 属性:
.NET Framework 类库提供检索自定义属性的方法。默认情况下,这些方法搜索属性继承层次结构;例如System.Attribute.GetCustomAttribute
搜索指定的属性类型,或扩展指定属性类型的任何属性类型。密封属性消除了通过继承层次结构的搜索,并且可以提高性能。[我的重点]
所以[Serializable]
是密封的,因为 .Net 反射检查属性更快。代价是你不能继承和扩展SerializableAttribute
。
如果需要,您可以创建自己的未密封属性(尽管您会收到代码分析警告)。
这有点让人困惑,属性是如何在继承中用于它们所应用的类的。最好使用一个例子:
[Serializable]
public class A
{
public int SimpleSerialisableProperty { get; set;}
}
public class B : A
{
public C ComplexReferenceProperty { get; set; }
}
[Serializable]
public class D : A
{
public bool AnotherSerialisableProperty { get; set;}
}
你问为什么SerializableAttribute.Inherited = false
,这就是为什么:
类A
被标记为[Serializable]
,它是。
但是,类B
继承A
并使用不可序列化的属性扩展它。如果 .Net 尝试序列化B
,它将遇到错误。
这Inherited = false
告诉 .Net 仅仅因为A
已被标记为[Serializable]
并非每个继承它的类也都是可序列化的。
现在类D
继承A
并且是可序列化的,所以它有自己的[Serializable]
属性。
最后,就设计而言,属性是扩展行为的好方法(属性网格中的漂亮 UI 编辑器等)。然而,他们在执行方面很糟糕。如果您需要您的客户以特定方式实现他们的实体类,那么abstract
基类或 aninterface
是一种更好的方法。如果你把它作为一个属性,那么你基本上是让他们知道这[Serializable]
是一个你可以处理任何一种方式的选项。