How come you can pass an array into a C# attribute class but not a VB.NET attribute class?


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


Comments (1)

  1. Another question answered.