强制类/方法的属性修饰

Posted

技术标签:

【中文标题】强制类/方法的属性修饰【英文标题】:Enforce Attribute Decoration of Classes/Methods 【发布时间】:2010-09-06 09:00:23 【问题描述】:

继我最近在Large, Complex Objects as a Web Service Result 上提出的问题之后。我一直在思考如何确保所有未来的子类都可序列化为 XML。

现在,显然我可以实现IXmlSerializable 接口,然后将读取器/写入器扔给它,但我想避免这种情况,因为这意味着我需要在任何时候实例化读取器/写入器,并且99.99% 的时间我将使用 string,所以我可以自己编写。

但是,为了序列化为 XML,我只是用 Xml??? 属性(XmlRootXmlElement)装饰类及其成员> 等),然后将其传递给 XmlSerializerStringWriter 以获取字符串。这一切都很好。我打算把返回字符串的方法放到一个通用的实用方法中,这样我就不用担心类型等了。

我关心的是:如果我不使用所需的属性装饰类,直到运行时才会抛出错误。

有没有办法强制属性装饰?这可以用 FxCop 完成吗?(我还没用过 FxCop)

更新:

抱歉耽搁了这些家伙,还有很多事情要做!

绝对喜欢在测试用例中使用反射而不是诉诸 FxCop(喜欢将所有东西放在一起)的想法。Fredrik Kalseth's answer 太棒了,感谢包含代码,因为它可能会让我有点挖掘想自己怎么做!

+1 给其他人以获得类似的建议 :)

【问题讨论】:

【参考方案1】:

我会编写一个单元/集成测试来验证任何符合某些给定条件的类(即子类 X)是否被适当地修饰。如果您将构建设置为与测试一起运行,则此测试失败时可能会导致构建失败。

更新:你说,“看起来我只需要卷起袖子,确保单元测试得到集体维护”——你不必这样做。只需编写一个通用测试类,它使用反射来查找所有需要断言的类。像这样的:

[TestClass]
public class When_type_inherits_MyObject

    private readonly List<Type> _types = new List<Type>();

    public When_type_inherits_MyObject()
    
        // lets find all types that inherit from MyObject, directly or indirectly
        foreach(Type type in typeof(MyObject).Assembly.GetTypes())
        
            if(type.IsClass && typeof(MyObject).IsAssignableFrom(type))
            
                _types.Add(type);
            
        
    

    [TestMethod]
    public void Properties_have_XmlElement_attribute
    
        foreach(Type type in _types)
        
            foreach(PropertyInfo property in type.GetProperties())
            
                object[] attribs = property.GetCustomAttributes(typeof(XmlElementAttribute), false);
                Assert.IsTrue(attribs.Count > 0, "Missing XmlElementAttribute on property " + property.Name + " in type " + type.FullName);
            
        
    

【讨论】:

【参考方案2】:

您可以编写单元测试来检查这种事情 - 它基本上使用反射。

鉴于这是可能的,我想也可以编写 FxCop 规则,但我从未做过这样的事情。

【讨论】:

【参考方案3】:

您可以编写 FxCop 规则,甚至可以通过在基类的构造函数中调用 GetType() 并反映返回的类型来检查属性。

【讨论】:

【参考方案4】:

一个好的 FXCop 规则(我发现我现在需要的)是检查添加到 ASP.NET 会话中的所有对象是否具有 Serializable 属性。我正在尝试从 InProc 会话状态转移到 SQL Server。我第一次请求一个页面时,我的网站炸毁了我,因为不可序列化的对象被存储在 Session 中。然后是在所有源代码中寻找在会话中设置对象的每个实例的任务...... FXCop 将是一个不错的解决方案。要做的事情...

【讨论】:

【参考方案5】:

您还可以使用此概念/后处理器来强制执行属性之间的关系,并在编译时使用类似的登录来强制执行类和属性之间的关系:

http://www.st.informatik.tu-darmstadt.de/database/publications/data/cepa-mezini-gpce04.pdf?id=92

【讨论】:

以上是关于强制类/方法的属性修饰的主要内容,如果未能解决你的问题,请参考以下文章

面向对象的过程继承封装多态;抽象类访问修饰符的使用引用类型强制转换方法重写@override与重载空指针异常super关键字

Java中各种(类方法属性)访问修饰符与修饰符的说明

static可选修饰符

static关键字

OC类属性了解一下-class作为属性修饰符

Java中各种(类方法属性)访问修饰符与修饰符的简单说明