C# 强制类/方法的属性修饰
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19454/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Enforce Attribute Decoration of Classes/Methods
提问by Rob Cooper
Following on from my recent question on Large, Complex Objects as a Web Service Result. I have been thinking about how I can ensure all future child classes are serializable to XML.
继我最近关于Large, Complex Objects as a Web Service Result 的问题之后。我一直在考虑如何确保所有未来的子类都可以序列化为 XML。
Now, obviously I could implement the IXmlSerializableinterface and then chuck a reader/writer to it but I would like to avoid that since it then means I need to instantiate a reader/writer whenever I want to do it, and 99.99% of the time I am going to be working with a stringso I may just write my own.
现在,显然我可以实现IXmlSerializable接口,然后将读取器/写入器夹在它上面,但我想避免这种情况,因为这意味着我需要在需要时实例化读取器/写入器,并且 99.99% 的时间我将使用一个字符串,所以我可以自己写。
However, to serialize to XML, I am simply decorating the class and its members with the Xml???attributes ( XmlRoot, XmlElementetc.) and then passing it to the XmlSerializerand a StringWriterto get the string. Which is all good. I intend to put the method to return the string into a generic utility method so I don't need to worry about type etc.
但是,要序列化为 XML,我只是用Xml装饰类及其成员???属性(XmlRoot、XmlElement等),然后将其传递给XmlSerializer和StringWriter以获取字符串。这一切都很好。我打算将返回字符串的方法放入通用实用程序方法中,这样我就不必担心类型等问题。
The this that concerns me is this: If I do not decorate the class(es) with the required attributes an error is not thrown until run time.
这让我担心的是:如果我不使用所需的属性装饰类,则直到运行时才会抛出错误。
Is there any way to enforce attribute decoration? Can this be done with FxCop?(I have not used FxCop yet)
有没有办法强制执行属性装饰?这可以通过 FxCop 完成吗?(我还没用过 FxCop)
UPDATE:
更新:
Sorry for the delay in getting this close off guys, lots to do!
很抱歉延迟关闭这些家伙,还有很多事情要做!
Definitely like the idea of using reflection to do it in a test case rather than resorting to FxCop (like to keep everything together).. Fredrik Kalseth's answerwas fantastic, thanks for including the code as it probably would have taken me a bit of digging to figure out how to do it myself!
绝对喜欢在测试用例中使用反射来完成它而不是诉诸 FxCop 的想法(喜欢将所有东西放在一起)。Fredrik Kalseth 的回答太棒了,感谢包含代码,因为它可能会让我有点挖掘弄清楚如何自己做!
+1 to the other guys for similar suggestions :)
+1 给其他人类似的建议:)
采纳答案by Fredrik Kalseth
I'd write a unit/integration test that verifies that any class matching some given criteria (ie subclassing X) is decorated appropriately. If you set up your build to run with tests, you can have the build fail when this test fails.
我会编写一个单元/集成测试,以验证符合某些给定标准(即子类化 X)的任何类都得到了适当的修饰。如果您将构建设置为与测试一起运行,则当此测试失败时,您可能会导致构建失败。
UPDATE: You said, "Looks like I will just have to roll my sleeves up and make sure that the unit tests are collectively maintained" - you don't have to. Just write a general test class that uses reflection to find all classes that needs to be asserted. Something like this:
更新:您说,“看来我只需要挽起袖子,确保集体维护单元测试”- 您不必这样做。只需编写一个通用测试类,它使用反射来查找所有需要断言的类。像这样的东西:
[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);
}
}
}
}
回答by samjudson
You can write unit tests to check for this kind of thing - it basically uses reflection.
您可以编写单元测试来检查此类事情 - 它基本上使用反射。
Given the fact this is possible I guess it would also be possible to write a FxCop rule, but I've never done such a thing.
鉴于这是可能的,我想也可以编写 FxCop 规则,但我从未做过这样的事情。
回答by Mark Cidade
You can write an FxCop rule or even check for the attributes by calling GetType() in the base class's constructor and reflecting over the returned type.
您可以编写 FxCop 规则,甚至可以通过在基类的构造函数中调用 GetType() 并反映返回的类型来检查属性。
回答by Larry Silverman
A good FXCop rule (and one which I am finding I need right now) would be to check that all objects that are being added to the ASP.NET Session have the Serializable attribute. I'm trying to move from InProc session state to SQL Server. First time I requested a page, my site blew up on me because non-serializable objects were being stored in Session. Then came the task of hunting through all the source code looking for every instance where an object is set in the Session... FXCop would be a nice solution. Something to work on...
一个好的 FXCop 规则(也是我发现我现在需要的规则)是检查添加到 ASP.NET 会话的所有对象是否具有 Serializable 属性。我正在尝试从 InProc 会话状态转移到 SQL Server。我第一次请求一个页面时,我的网站炸毁了我,因为不可序列化的对象被存储在 Session 中。然后是在所有源代码中寻找在会话中设置对象的每个实例的任务...... FXCop 将是一个不错的解决方案。有事要做……
回答by Professional Sounding Name
You can also use this concept/post-processor to enforce relationships between attributes and use similar login to enforce relationships between classes and attributes at compile time:
您还可以使用这个概念/后处理器来强制属性之间的关系,并在编译时使用类似的登录来强制类和属性之间的关系:
http://www.st.informatik.tu-darmstadt.de/database/publications/data/cepa-mezini-gpce04.pdf?id=92
http://www.st.informatik.tu-darmstadt.de/database/publications/data/cepa-mezini-gpce04.pdf?id=92