Roslyn: Tuples in Attributes

Created on 1 Oct 2017  路  11Comments  路  Source: dotnet/roslyn

I'm using VS 2017.

I tried to create a simple attribute class who's constructor accepts a single Tuple of type (some-enum,string). This compiles.

However when I try to attach the attribute to some member in some class I get CS0181 "Attribute constructor parameter 'Parameters' has type '(API.Disposition, string)', which is not a valid attribute parameter type".

The attribute use in this case looks like this:

[QueryParameters((Optional,"gradeType"))]

If it's not a valid parameter type why does the attribute class itself compile fine? Here's the class itself:

`

[AttributeUsage(AttributeTargets.Field)]
public class QueryParametersAttribute : Attribute
{
    public QueryParametersAttribute ((API.Disposition,string) Parameters)
    {
          // TBD
    }
}

`

Incidentally, searching the web for CS0181 lists a result:

17.1.3 Attribute parameter types (C#) - msdn.microsoft.com

which when clicked leads to this unhelpful page:

https://www.microsoft.com/en-us/download/details.aspx?id=55979

Area-Compilers Area-Language Design Resolution-Answered Resolution-By Design

Most helpful comment

why would you pass a tuple into an attribute, rather than passing two arguments/properties?

Because this way you could support an array of them. It could be a nice way to allow things like a params argument of key-value pairs.

FWIW, I just want to reiterate this. Being able to pass an array of tuples to an attribute would be good.

All 11 comments

The parameter types permitted in the application of an attribute is limited by the CLR to the subset of types listed in that article. Without modification to the CLR there's nothing that the compiler can do to circumvent that limitation. But you can still instantiate an attribute in code so other constructors of arbitrary types are allowed.

Incidentally, searching the web for CS0181 [鈥 leads to this unhelpful page

CS0181 is not among the errors listed in documentation. Since you found it confusing, maybe it should be? I'm not sure what is the rule about which errors are documented, but you might want to consider creating an issue on the docs repo, asking for CS0181 to be documented.

@HaloFour @svick - Thanks for the updates. I guess my primary problem here is that the attribute class itself compiles despite the fact that the arg is invalid for an attribute, shouldn't we get an error here?

@Korporal

Not technically. You're always allowed to instantiate an attribute via code rather than using attribute syntax in which case those limitations don't apply. But I could a warning wave candidate if an attribute type lacks any constructors that could be invoked by the runtime.

shouldn't we get an error here?

No, that would be a breaking change. As @HaloFour pointed out, code like var a = new QueryParametersAttribute((Optional,"gradeType")); is valid (weird, but valid), so it can't be an error.

I think it could be a warning that's part of a warning wave, though (https://github.com/dotnet/roslyn/issues/1580).

OK thanks, you're quite right. Be nice if I _could_ use it with Tuples though...!

For that you might want to open an issue on the CoreCLR repo. The CLR would need a way to recognize the family of tuple types and support embedded constant values of those types.

The comments are correct. The current behavior is by-design.

My initial thought was this would be nice to support. But on second thought, why would you pass a tuple into an attribute, rather than passing two arguments/properties? The benefit seems small, especially given the hurdles to make this happen.

why would you pass a tuple into an attribute, rather than passing two arguments/properties?

Because this way you could support an array of them. It could be a nice way to allow things like a params argument of key-value pairs.

why would you pass a tuple into an attribute, rather than passing two arguments/properties?

Because this way you could support an array of them. It could be a nice way to allow things like a params argument of key-value pairs.

FWIW, I just want to reiterate this. Being able to pass an array of tuples to an attribute would be good.

why would you pass a tuple into an attribute, rather than passing two arguments/properties?

Because this way you could support an array of them. It could be a nice way to allow things like a params argument of key-value pairs.

FWIW, I just want to reiterate this. Being able to pass an array of tuples to an attribute would be good.

agree. may we hope this happen?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

stephentoub picture stephentoub  路  167Comments

gafter picture gafter  路  279Comments

mgravell picture mgravell  路  119Comments

MadsTorgersen picture MadsTorgersen  路  170Comments

ghost picture ghost  路  229Comments