Q:  In C# you can pass an array into an attribute class using the code below but when you try to do this from VB.NET you get an error.  Why can’t you do this in VB.NET?

 

public sealed class FooAttribute : Attribute

{

       private int[] intarr;

       public int[] IntArray

       {

              set

              {

                     intarr = value;

              }

              get

              {

                     return intarr;

              }

       }

}

 

[Foo(IntArray=new int[]{1,2,3})]

class Class1

{

              }

 

 


<Foo(New Integer() {1, 2, 3})> _

Public Class test

    Public x As Integer() = {1, 2, 3}

End Class

 

Public NotInheritable Class FooAttribute

    Inherits Attribute

    Private intarr() As Integer

 

    Public Sub New()

 

    End Sub

 

    Public Property IntArray() As Integer()

        Get

            Return intarr

        End Get

        Set(ByVal Value As Integer())

            intarr = Value

        End Set

    End Property

End Class 'FooAttribute

 

 

Error:  Constant expression is required.

 

 

 

A:  The language specification for Visual Basic .NET does not allow for expressions to be passed in as arguments within Attribute Blocks.  Attribute block arguments must be constant expressions.  You can call methods with the expression “New Integer() {}”.  There is a tiny blurb in the docs that mentions this:  Note that in Visual Basic, constructors for an attribute class should not use a ParamArray argument.

 

While the above VB.NET code does not work, the following does work.

 

    test(New Integer() {1, 2, 3})

 

where test is defined as:

 

    Public Sub test(ByVal x As Integer())

    End Sub

 

Here’s the language definition for both Application Block Arguments and Method Call Arguments

 

Attribute Arguments

AttributeArguments ::=
   AttributePositionalArgumentList |
   AttributePositionalArgumentList , VariablePropertyInitializerList |
   VariablePropertyInitializerList

 

AttributePositionalArgumentList ::=
   ConstantExpression |
   AttributePositionalArgumentList , ConstantExpression

 

VariablePropertyInitializerList ::=
   VariablePropertyInitializer
   VariablePropertyInitializerList , VariablePropertyInitializer

VariablePropertyInitializer ::= Identifier : = ConstantExpression

 

 

Argument Lists

ArgumentList ::=
   PositionalArgumentList , NamedArgumentList |
   PositionalArgumentList |
   NamedArgumentList

 

PositionalArgumentList ::=
   ArgumentExpression |
   PositionalArgumentList , [ ArgumentExpression ]

 

NamedArgumentList ::=
   Identifier : = ArgumentExpression |
   NamedArgumentList , Identifier : = ArgumentExpression

ArgumentExpression ::= Expression | DelegateArgumentExpression

 

 

For a similar issue regarding Attributes and why you can do somethings in VB.NET but not C# see Eric Gunnerson’s post:  http://blogs.msdn.com/csharpfaq/archive/2004/05/11/130236.aspx