Roslyn: VS2017 IDE will not accept decimal constants as attribute arguments (CS0181, CS0182)

Created on 2 Feb 2017  路  5Comments  路  Source: dotnet/roslyn

_From @ericwj on January 26, 2017 3:0_

Declaring a decimal typed argument to an attribute constructor in VS 2017 will produce CS0181.
Providing a decimal typed argument to an attribute constructor that takes say object in VS 2017 will produce CS0182.

In both cases, building from the command line will work.

using System;

class DecimalAttribute : Attribute
{
    public DecimalAttribute(decimal value) { }
}
class AnyAttribute : Attribute
{
    public AnyAttribute(object value) { }
}
class Program
{
    // 1>Program.cs(14,3,14,5): error CS0181: Attribute constructor parameter 'value' has type 'decimal', which is not a valid attribute parameter type
    [Decimal(123m)] public int CS0181 { get; set; }
    // 1>Program.cs(15,7,15,11): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
    [Any(123m)] public int CS0182 { get; set; }
}

_Copied from original issue: aspnet/Tooling#971_

Area-Compilers Resolution-By Design

Most helpful comment

Okay well that's slightly unexpected. I write decimal in navy blue. Blindly expect the compiler to be able to write constants of it...

But then how do you explain I can build from the command line but VS 2017 will give me those errors and refuse to build?

All 5 comments

This has nothing to do with VS2017, it works like this since C# 1.0. Decimal isn't a primitive type and the runtime doesn't allow its use with attributes.

From https://github.com/dotnet/csharplang/blob/master/spec/attributes.md#attribute-specification

An expression E is an _attribute_argument_expression_ if all of the following statements are true:

  • The type of E is an attribute parameter type (Attribute parameter types).
  • At compile-time, the value of E can be resolved to one of the following:

    • A constant value.

    • A System.Type object.

    • A one-dimensional array of _attribute_argument_expressions_.

and

Attribute parameter types

The types of positional and named parameters for an attribute class are limited to the attribute parameter types, which are:

  • One of the following types: bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • The type object.
  • The type System.Type.
  • An enum type, provided it has public accessibility and the types in which it is nested (if any) also have public accessibility (Attribute specification).
  • Single-dimensional arrays of the above types.
  • A constructor argument or public field which does not have one of these types, cannot be used as a positional or named parameter in an attribute specification.

Okay well that's slightly unexpected. I write decimal in navy blue. Blindly expect the compiler to be able to write constants of it...

But then how do you explain I can build from the command line but VS 2017 will give me those errors and refuse to build?

@ericwj Can you provide a minimal sample to reproduce this? I've never seen a successful build from the command line with a decimal where a constant is expected.

I basically cannot reproduce. I'm guessing the issue is not so very important as it appears at least the latest version of dotnet shows the behavior you explained to be correct.

If I build it with rc3, it'll complain with CS0181 as it appears it should.

If I build it with any other version on the machine on which I originally ran into this, it'll complain about Program missing a suitable Main method. It does that even after adding one. I'm guessing there are issues with my .csproj. I can't figure out what my global.json and csproj looked like when it did build. I can't get it to build right now, although I can get rid of the CS0181 without removing the code for them. I'm guessing these are MSBuild issues basically. E.g. I had it complain that I had two '<Compile/>' elements.

Console output:
Console Output

Was this page helpful?
0 / 5 - 0 ratings