2

Why does the code below give me the exception:

CSC error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

On my build server?

/// Customer.cs...

[Search(SearchAttribute.SearchDisplay.Regular)] 
public Category Category
{
     get; set;
}

public enum Category : byte
{
    X = 0x01,
    Y = 0x02,
    ...
}

/// SearchAttribute.cs...

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class SearchAttribute : Attribute
{
    public SearchDisplay Display { get; private set; }

    public enum SearchDisplay
    {
        None = (byte) 0x01,
        Regular = (byte) 0x02
    }

    public SearchAttribute(SearchDisplay display, string columnName = null)
        : base()
    {
        Display = display;
    }
}

Many Thanks.

Infuriatingly, it builds fine in VS2012. I'm unsure what version of the compiler runs on the server - but I'm fairly sure it's not the 2012 one.

UPDATE

Thanks to the answerers below I've figured this out:

I am using VS2012, but the build server is still using the VS2010 build process. There is a bug in the VS2010 / C#4 compiler that occurs when a null valued default parameter is used in an attribute. I can get around this 3 ways:

  1. Don't use a default parameter - public SearchAttribute(SearchDisplay display, string columnName)
  2. Use a empty string - public SearchAttribute(SearchDisplay display, string columnName = "")
  3. Update my build server.

I am going with 2 just now. 3 is something that I will need to think about at another time.

1

2 Answers 2

3

I think the Customer.cs file is in a separate assembly (C# project), and that assembly references the assembly (project) in which SearchAttribute.cs is located.

For the enum SearchDisplay and the optional parameter columnName in the constructor to work correctly, it is then vital that both assemblies are recompiled in the correct order. I suspect that wasn't the case on your build server. The dependent assembly was probably compiled with a reference to an old version of the assembly where SearchAttribute is located.

UPDATE

See all the linked threads on the right. This is a bug that they say is fixed with Visual Studio 2012 (C# 5 compiler). It happens only when the default value of the optional parameter is null. In my first test I made the silly decision to use another string (which would be recognizable), but it doesn't happen with another string. (Will erase my comment below.)

When the usage of the attribute is in the same assembly as the the attribute class itself, it helps to give the null literal an explicit type, as in:

public SearchAttribute(SearchDisplay display, string columnName = (string)null)
...

With this, it seems to work as long as all usages are in the same assembly as the above construtor. However, in your case they are in different assemblies.

Problem goes away if you are willing to use the empty string instead:

public SearchAttribute(SearchDisplay display, string columnName = "")
...

Otherwise, I suggest you use the old pre-C#-4-style

[Search(SearchAttribute.SearchDisplay.Regular)] 
public Category Category
...

[Search(SearchAttribute.SearchDisplay.Regular, ColumnName = "Changed!")] 
public Category AnotherCategory
...

This works with no columnName parameter in the constructor, as long as there's a class member (instance property or field) called ColumnName. That ColumnName must not be read-only or get-only.

Sign up to request clarification or add additional context in comments.

3 Comments

You are absolutely correct. Was the error nothing to do with the code, but simply build order? Or is Daniel A. White correct too?
@Kryptonite I'm not sure if it's supported. I would think it was, but the thread Attributes and Named/Optional constructor parameters not working confuses me a bit.
@Kryptonite Update: Other threads here on Stack Overflow agree it's a bug. See my edited answer above.
1

Don't you mean

 [Search(SearchAttribute.SearchDisplay.Regular)] 

6 Comments

Yes, Sorry I do mean that. Edited.
@Kryptonite try removing the default value from columnName. i dont think that is supported.
what is your build server running?
@Kryptonite no the compiler and .net version? is 4.5 installed?
No. Neither VS nor the server have 4.5. All projects in my solution target 4.0.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.