您已经完成或听说过哪些 CLR/C# 代码中的自定义属性很酷的应用程序?标准属性的有趣新用途也可以!
编辑:由于 Java 的注解似乎与 CLR 的属性相同,因此使用 Java 注解也是有效的。
您已经完成或听说过哪些 CLR/C# 代码中的自定义属性很酷的应用程序?标准属性的有趣新用途也可以!
编辑:由于 Java 的注解似乎与 CLR 的属性相同,因此使用 Java 注解也是有效的。
[TypeDescriptionProvider]
可用于提供自定义运行时属性模型 - 完全不同的属性,或者更快的属性还有一些经常被忽视的核心:
[TypeForwardedTo]
- 用于在组件之间移动类型而无需重新构建[PrincipalPermission]
- 用于自动对成员强制执行安全性虽然不是严格意义上的 C#,但我发现 Java 注释(= C# 属性)用于标记学生作业的一个有趣用途。每学期我都会给学生编程一个打标机器人,结果发现一年级的学生由于某种原因似乎不能准确地遵循指令,这当然导致打标机器人出现故障。所以我要做的是通过他们的代码,找到所有不符合规范的方法并修复它们。然后我在每个错误的方法上都添加了注释(=attribute),告诉标记机器人将它们标记下来。这可能是我认为最简单直接的方法。
查看xUnit并了解如何使用属性来标记单元测试的预期行为以及将数据馈送到测试中。属性的使用方式比 MSTest 或 NUnit 更有意义。
从Samples\TestMethodExtensibility\Example.cs:
public class Example
{
static int val;
[RepeatTest(5, Timeout=250)]
public void RepeatingTestMethod()
{
Thread.Sleep(100);
Assert.Equal(2, 2);
if (val == 0)
{
val++;
Thread.Sleep(1000);
}
}
}
从test.xunit.extensions\DataTheories\TheoryAttributeTests.cs:
internal class TestMethodCommandClass
{
public static IEnumerable<object[]> EmptyData
{
get { return new object[0][]; }
}
public static IEnumerable<object[]> NullData
{
get { return null; }
}
public static IEnumerable<object[]> TheoryDataProperty
{
get { yield return new object[] { 2 }; }
}
[Theory, PropertyData("EmptyData")]
public void EmptyDataTheory() { }
[Theory, PropertyData("NullData")]
public void NullDataTheory() { }
[Theory, OleDbData(
@"Provider=Microsoft.Jet.OleDb.4.0; Data Source=DataTheories\UnitTestData.xls; Extended Properties=Excel 8.0",
"SELECT x, y, z FROM Data")]
public void TestViaOleDb(double x,
string y,
string z) { }
[Theory, PropertyData("TheoryDataProperty")]
public void TestViaProperty(int x) { }
[Theory, ExcelData(@"DataTheories\UnitTestData.xls", "SELECT x, y, z FROM Data")]
public void TestViaXls(double x,
string y,
string z) { }
}
详情见:
nunit 当然
属性的使用被肯特贝克引以为豪:
NUnit 2.0 是惯用设计的一个很好的例子。大多数移植 xUnit 的人只是音译 Smalltalk 或 Java 版本。这也是我们最初对 NUnit 所做的。这个新版本是 NUnit,因为它本来是在 C# 中完成的。
我有一个案例,我想将接口的实际实现也呈现为数据。这当然可以通过反射来完成,但是通过在我想作为数据公开的成员上使用特定属性,我可以封装执行此操作所需的工作。
最终结果是我创建了我的实现,装饰了所需的成员,然后我可以通过代码和数据查询成员,而无需在每种情况下都执行反射代码。
有时,我使用属性来装饰类或方法,并使用反射来获取“属性”数据。
可能有点难以解释,但我使用属性的最后一件事是在一个数据库中有几个实体的系统中。
每个实体都有某种“代码”,每个实体也可以有一些解释规则。
在我的项目中,我有一个实体类,它表示数据库中存在的一个实体,并且我还有一组“规则”类。一个规则类包含给定实体的解释逻辑。
为了将某个“规则”(解释)“链接”到我的实体的特定实例,我创建了一个自定义属性。
我用这个属性装饰我的“规则”类,并通过这个属性,我定义了哪个实体这是一个规则。然后,当我从数据库加载实体时,我将正确的规则注入到该实体中。
一些代码让事情变得清晰:
public class MyEntity
{
public string Code
{
get;
private set;
}
public bool IsValidFor( ... )
{
IRule rule = RuleRegistry.GetRuleFor(this);
if( rule.IsValid() ) ...
}
}
[RuleAttrib("100")]
public class MyRule : IRule
{
public bool IsValid()
{
}
}
这只是一个小例子,但我想你会明白的。
MyRule 类的 RuleAttrib 属性表示,这是一个应该应用于具有代码“100”的 MyClass 实例的规则。
RuleRegistry 实例能够为当前实体检索正确的 IRule(使用反射)。
我结合 Postsharp 使用属性的另一个例子是“锁定”系统的实现:http: //fgheysels.blogspot.com/2008/08/locking-system-with-aspect-orientation.html
我们使用自定义 java 注解来标记某些方法的特殊用途,主要针对开发人员:
@ScriptingAPI
-- 标记作为我们脚本 API 的一部分公开的代码(警告开发人员更改可能会影响公共 API)@Transaction
-- 在数据库外观上标记正在启动/提交事务的方法(我们有一个尊重此注释的专用事务处理程序类)@NeedsAttentionToSupportFoo
-- 如果我们知道功能 Foo 是我们需要在不久的将来解决的要求,我们使用注释来标记我们需要触摸以支持它的代码,即当我们遇到一段代码时我们认为“啊,这需要更改以支持 Foo”,我们对其进行注释。如果 Foo 的实现被推迟或永远不会发生,删除注释比恢复散布在代码中的过早优化更容易。此 java 专家时事通讯介绍了自定义注释的另一个很好的示例用法:在所有子类中强制执行公共无参数构造函数。
Castle 的ActiveRecord使用属性。它隐藏了 NHibernate 的一些设置复杂性,通过使用属性来装饰您的模型对象,这些属性指示应该持久化到数据库的类和字段(以及如何持久化)。验证组件中还使用属性将基于模型的验证添加到 ActiveRecord 和Monorail堆栈中。