Why are C # attributes so limited?

I understand that they are compilation time, so they cannot be universal and must be initialized with constant values. But:
Why can't they get the information you would get if you reflected what they apply to?

Why can't they accept lambda expressions, functions or delegates? Are constants a compiler?

Attributes can be a phenomenally powerful declarative tool if only one of the above was true, instead they are more like comments that can be read through reflection.

It was a kind of pomp, but I really want to know why they seem such a half-useful feature.

Here is what I wanted to do. It was assumed that this is an api for displaying values ​​from resources through a function assigned to an attribute to the property to which the attribute is applied. Note that an abstract class should not exist if Attributes can know what they reflect. I publish this because someone wanted to know why I would like to provide functions for constructor attributes, and possibly because what I'm trying to do is already done.

public delegate void PropertyHandler(object parent, PropertyInfo property, object value); [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class FromResourceAttribute : Attribute { private static readonly PropertyHandler m_defaultHandler = (parent, property, value) => { property.SetValue(parent, value, null); }; public PropertyHandler Handler { get; set; } public FromResourceAttribute(PropertyHandler handler) { Handler = handler; } public FromResourceAttribute() { Handler = m_defaultHandler; } } public abstract class ResourceDependent { public ResourceDependent(ResourceManager resources) { var resourceDependentProperties = from property in GetType().GetProperties() let fromResourceAttributes = property.GetCustomAttributes(typeof(FromResourceAttribute), true) where fromResourceAttributes.Count() == 1 let propertyHandler = ((FromResourceAttribute)fromResourceAttributes.Single()).Handler select new { Info = property, Handler = propertyHandler }; foreach(var property in resourceDependentProperties) { property.Handler(this, property.Info, resources.GetObject(property.Info.Name)); } } } class ResourceDependentTest : ResourceDependent { [FromResource] public string Data { get; set; } [FromResource((parent, property, value) => property.SetValue(parent, ((string)value).Split('|'), null))] public string[] Data2 { get; set; } static PropertyHandler Data3Handler = (parent, property, value) => { //Magic }; [FromResource(Data3Handler)] public int Data3 { get; set; } public ResourceDependentTest() : base(Properties.Resources.ResourceManager) { } } 
+6
c # attributes
source share
4 answers

Why do they not have the information that you would receive if you reflected what they apply to?

Part of the reason is that attributes should not be applied to anything. This is completely legal for a new attribute in a peremptory code that is not tied to anything.

 // Not attached var attrib = new CLSCompliantAttribute(false); 

Why can't they accept lambda expressions, functions or delegates? Are constants a compiler?

All of this solves the question of why delegates cannot be part of an attribute. Their main delegates consist of two parts: 1) an instance and 2) a pointer to a method. # 1 pretty much kills it, because the instance is not constant and cannot be part of the attribute value.

There are several other cases that exist with delegates, including a delegate, to static methods and expression trees. They have similar problems, although the fact that all parts of the expression are not constant, therefore they are not encoded in the attribute value.

+11
source share

In fact, the question of why they cannot be generic was answered earlier, and, according to Eric Lippert, they are not supported simply because they add complexity to the language, and this simply is not considered worthwhile until now. This, of course, is not because he compiles time. In IL, you can obviously create common attributes. ( Link .)

As for why they can't accept lambda expressions, etc., I assume the same reason. The delegate request has been Microsoft Connect since 2006. You can vote for him if you want.

+5
source share

The short, short version is that IL no longer supports functionality; see ECMA-335 Section II §21 User Attributes and Section II §23.3 User Attributes.

To summarize §23.3, user attributes use a special serialization format that is stored in IL, not Binary Serialization , not XML or SOAP . Quote from the standard §23.3:

FieldOrPropType field must be exactly one of: ELEMENT_TYPE_BOOLEAN , ELEMENT_TYPE_CHAR ELEMENT_TYPE_I1 , ELEMENT_TYPE_U1 , ELEMENT_TYPE_I2 , ELEMENT_TYPE_U2 , ELEMENT_TYPE_I4 a one-dimensional, zero array is specified as a single byte 0x1D followed by a FieldOrPropType element type. (See §23.1.16) An enumeration is specified as one 0x55 byte followed by a SerString. Following SerString.

The obvious answer, of course, is “why doesn't it support the IL / serialization format support method, etc. And the obvious answer, of course, is that they felt that it was optional, and / or that the IL was further inflated.

(Interesting aside: type references are actually implemented using a string containing the fully qualified assembly name of this type. By the same logic, I believe that a method reference can be "encoded" using the type name and encoding for the method, but I suspect that it will be "fragile" as adding / modifying methods can upset the situation.)

+2
source share

I don’t really fit into attributes (because, in my opinion, they are designed for developers of tools like nunit), but I think you already answered your question: Attributes are a compile-time constant

Attribute parameters are limited to constant values ​​of the following Types:

 * Simple types (bool, byte, char, short, int, long, float, and double) * string * System.Type * enums * object (The argument to an attribute parameter of type object 

must be a constant value of one of the types above.) * One-dimensional arrays of any of the above types

http://msdn.microsoft.com/en-us/library/aa288454%28VS.71%29.aspx#vcwlkattributestutorialanchor1

while the return value is lambdas, delegates and functions are not.

I really don't want to know what the code with heavy use of lambda in attributes looks like, should be pretty mess.

+1
source share

All Articles