BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News C# 8: Generic Attributes

C# 8: Generic Attributes

Leia em Português

This item in japanese

Bookmarks

Attributes have been part of .NET since the beginning. As such, they were created before generics were introduced and never quite caught up, which means if you want to refer to a type in the attribute, you must expose a Type parameter or property. For example,

[TypeConverter(typeof(X))]

There are some limitations to this pattern. In the above example, X must have a parameterless constructor and inherit from TypeConverter. This cannot be enforced by the compiler, so the developer won't be made aware of mistakes until runtime.

If instead we used a generic type parameter, then constraints can be applied enforcing the rule at compiler time. And the syntax will be slightly cleaner.

[TypeConverter<X>]

In theory the Allow Generic Attributes proposal is a very simple change. The CLR already supports the concept; it is just a matter of exposing it in the .NET languages. But theory and practice often don't match and just because the CLR is supposed to support it doesn't necessarily mean it does. Jan Kotas explains:

I think that the nature of this issue is similar to ref locals and returns. ref locals and returns are not keyed by any API. They should work just fine with existing runtimes, tools and libraries in theory. In practice, they do not work just fine because they expose pre-existing bugs and limitations because of the paths handling them were never exercised, or they were explicitly not expected. The bugs and issues related to byref returns are just starting to show up as people are starting to use the feature and finding places where it does not work. I think that is fine and expected. We should acknowledge it, and not react to it by pulling back the feature like we have done it for default valuetype constructors some time ago.

This feature is pretty similar. There is nothing in ECMA that prohibits generic attributes, and they should work just fine in theory. In practice, they do not. A number of parts throughout the system have to be updated to make them work well:

  • There is more than one runtime to worry about as you have said (Mono, CoreRT, full framework)
  • Some the tools that operate on IL are likely going to be affected too (compilers, Cecil-based or CCI2-based tools)
  • New APIs for accessing the generic attributes maybe needed (e.g. the existing reflection APIs do not allow you to access the generic attributes efficiently - you have to always enumerate)

One limitation of this proposal is the attributes must be "closed" at compile time. To illustrate what that means, here is an example of an open generic from the proposal.

[SomeAttribute<T>]
public void DoSomething<T>(T input) { }

Since T is not defined at compile time, reflection will not know what to return for this expression.

typeof(GenericClass<>).GetMethod("DoSomething").GetCustomAttributes()

Status

Currently the Generic Attributes feature is listed on the C# 8 roadmap with the status "In Progress".

Rate this Article

Adoption
Style

BT