C# 在 dotnet/.NET 中实现自定义属性的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/975824/
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
What's the best way to implement custom attributes in dotnet/.NET?
提问by IAmAN00B
I don't really understand attributes. I've read all kinds of books & posts on them, but I just don't get it.
我真的不明白属性。我读过关于它们的各种书籍和帖子,但我就是不明白。
Since I don't understand them, I also don't understand how to effectively use them.
由于我不了解它们,我也不明白如何有效地使用它们。
1) Can you give me a good definition of what an attribute is & what it's used for?
1)你能给我一个关于属性是什么以及它的用途的很好的定义吗?
2) Can you give me a good code example in C# of how to make and consume a custom attribute?
2)你能在 C# 中给我一个很好的代码示例,说明如何创建和使用自定义属性?
采纳答案by cjk
Say you've got a class with a series of properties that you are going to walk through using reflection. Any that are strings may need to be validated to check they are not longer than a certain amount.
假设您有一个包含一系列属性的类,您将使用反射遍历这些属性。任何字符串都可能需要验证以检查它们的长度不超过一定数量。
You could then create a TextLength
attribute, with a default integer constructor and integer property/field. You could then read your attribute on each string property in your class and compare the length of the property value to the number specified in the attribute.
然后TextLength
,您可以使用默认整数构造函数和整数属性/字段创建一个属性。然后,您可以读取类中每个字符串属性的属性,并将属性值的长度与属性中指定的数字进行比较。
Code:
代码:
public class TextLengthAttribute : Attribute
{
private int length;
public int Length { get { return length; } set { length = value; } }
public TextLengthAttribute(int num) { this.length = num; }
}
public class MyClass
{
[TextLength(10)]
public string Property1;
[TextLength(20)]
public string Property2;
}
public class ClassReader
{
public static void Main()
{
MyClass example = MyClass.GetTestData();
PropertyInfo[] props = typeof(MyClass).GetProperties();
foreach (PropertyInfo prop in props)
{
if (prop.ValueType == typeof(String)
{
TextLengthAttribute[] atts =
(TextLengthAttribute)[]prop.GetCustomAttributes(
typeof(TextLengthAttribute), false);
if (prop.GetValue(example, null).ToString().Length >
atts[0].Length)
throw new Exception(prop.name + " was too long");
}
}
}
}
Note: untested
注:未经测试
回答by tanascius
Have a lot at e.g. log4PostSharp. They use attributes to introduce AOP behaviour.
有很多在例如log4PostSharp。他们使用属性来引入 AOP 行为。
That's an attribute I used once, to give properties a unit (like seconds, meter, ...)
这是我曾经使用过的一个属性,用于给属性一个单位(如秒、米、...)
[AttributeUsage( AttributeTargets.Property )]
public sealed class UnitAttribute : Attribute
{
public UnitAttribute( Unit unit )
{
Unit = unit;
}
public Unit Unit { get; private set; }
}
It was used on properties, like this:
它用于属性,如下所示:
[Unit( Unit.Meter )]
public float Distance { get; set; }
You can later retrieve the attribute to show it on the GUI.
您可以稍后检索该属性以在 GUI 上显示它。
回答by Andrew Hare
I could give you an example but it would pale in comparison to this fine article:
我可以举一个例子,但与这篇优秀的文章相比,它会显得苍白无力:
Defining and Using Custom Attribute Classes in C#
The complex, component-style development that businesses expect out of modern software developers requires greater design flexibility than the design methodologies of the past. Microsoft's .NET Framework makes extensive use of attributes to provide added functionality through what is known as "declarative" programming. Attributes enhance flexibility in software systems because they promote loose coupling of functionality. Because you can create your own custom attribute classes and then act upon them, you can leverage the loose coupling power of attributes for your own purposes.
与过去的设计方法相比,企业期望现代软件开发人员进行复杂的组件式开发需要更大的设计灵活性。Microsoft 的 .NET Framework 广泛使用属性,通过所谓的“声明式”编程提供附加功能。属性增强了软件系统的灵活性,因为它们促进了功能的松散耦合。因为您可以创建自己的自定义属性类,然后对它们进行操作,所以您可以为自己的目的利用属性的松散耦合能力。
回答by jerryjvl
回答by Kieron
An attribute is used to provide meta data about any member (fields, class etc).
属性用于提供有关任何成员(字段、类等)的元数据。
You can create them by inheriting from Attribute, and consume them by using the Attribute.GetCustomAttributemethod.
您可以通过从Attribute继承来创建它们,并通过使用Attribute.GetCustomAttribute方法来使用它们 。
An example of a default attribute is the PrincipalPermissionAttributewhich only allows authenticated users to access certain resources. For example:
默认属性的一个示例是PrincipalPermissionAttribute,它只允许经过身份验证的用户访问某些资源。例如:
[PrincipalPermission (SecurityAction.Demand, Role="Supervisor")]
public class DoTheThingPage : Page
{
////
}
In this example, we have an ASP.NET page that can only be viewed by an authenticated user that belongs to the 'Supervisor' role.
在此示例中,我们有一个 ASP.NET 页面,只能由属于“主管”角色的经过身份验证的用户查看。
(This attribute is automatically read by the security sub-system in ASP.NET)
(此属性由 ASP.NET 中的安全子系统自动读取)
Also note that the 'Attribute' part of the class name wasn't used, it's a convention within .NET.
另请注意,未使用类名的“属性”部分,这是 .NET 中的约定。
回答by Vasu Balakrishnan
We have a requirement to display Enum Values in a dropdown in a specific sort order. We implemented using Custom Attributes.
我们需要以特定排序顺序在下拉列表中显示枚举值。我们使用自定义属性实现。
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)]
public class EnumSortAttribute : Attribute
{
public int SortOrder;
public bool SortByDescription;
}
[EnumSort(SortByDescription=true)]
public enum EnumSortByDescription
{
[Description("enO")]
One = 1,
[Description("2")]
Two = 2,
Three = 3,
[Description("rouF")]
Four = 4
}
public enum EnumCustomSortOrder
{
[EnumSort(SortOrder = 3)]
One = 1,
[EnumSort(SortOrder = 1)]
Two = 2,
[EnumSort(SortOrder = 2)]
Three = 3
}
回答by Rinat Abdullin
Attribute is just a way to add additional information (metadata)to the class, struct or some member. This meta-data could be retrieved by other code in order to make some decisions.
属性只是向类、结构或某些成员添加附加信息(元数据)的一种方式。该元数据可以由其他代码检索以做出一些决定。
Simplest exampleis SerializableAttributefrom the .NET. It indicates that the class could be serialized by a BinaryFormatter later on.
最简单的例子是.NET 中的SerializableAttribute。它表明该类稍后可以由 BinaryFormatter 序列化。
Here's another example- we could mark some classes in our code with ImmutableAttribute to indicate that they don't have any mutable fields and are OK for multi-threaded operations:
这是另一个例子——我们可以用 ImmutableAttribute 在我们的代码中标记一些类,以表明它们没有任何可变字段并且可以用于多线程操作:
[Immutable]
public sealed class ProcessingMessage
{
//... some code that should be thread-safe
}
Then, we could create a unit test that finds all classes with the attribute and ensures that they are immutable indeed:
然后,我们可以创建一个单元测试来查找具有该属性的所有类并确保它们确实是不可变的:
[Test]
public void Immutable_Types_Should_Be_Immutable()
{
var decorated = GlobalSetup.Types
.Where(t => t.Has<ImmutableAttribute>());
foreach (var type in decorated)
{
var count = type.GetAllFields().Count(f => !f.IsInitOnly && !f.IsStatic);
Assert.AreEqual(0, count, "Type {0} should be immutable", type);
}
}