-
Sep 7th, 2010, 01:46 PM
#1
Optional and named parameters in an Attribute..?
Hi,
I have a custom Attribute class where the constructor takes one fixed parameter and two optional parameters. It is my understanding that one can supply one or more optional parameters by using 'named parameters' such as this:
Code:
Private Sub CallMethod()
Me.OptionalMethod(-1, z:=1)
End Sub
Private Sub OptionalMethod(ByVal x As Integer, Optional ByVal y As Integer = 0, Optional ByVal z As Integer = 10)
'...
End Sub
This way I skip the 'y' parameter and simply let it use the default value of 0. This works fine for any class, except apparently for attributes...
This is my attribute class:
vb.net Code:
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False)> _
Public Class GridOptionsAttribute
Inherits System.Attribute
Public Sub New(ByVal visible As Boolean, Optional ByVal text As String = Nothing, Optional ByVal index As Integer = -1)
_DisplayName = text
_Visible = visible
_DisplayIndex = index
End Sub
Private _DisplayName As String
Public ReadOnly Property DisplayName() As String
Get
Return _DisplayName
End Get
End Property
Private _Visible As Boolean
Public ReadOnly Property Visible() As Boolean
Get
Return _Visible
End Get
End Property
Private _DisplayIndex As Integer
Public ReadOnly Property DisplayIndex() As Integer
Get
Return _DisplayIndex
End Get
End Property
End Class
When I try to use it, I cannot seem to use named parameters:
Huh?
Well, I thought, perhaps Attributes don't support named parameters. I know they can behave a little weird (they don't support all types in their arguments for example I think), so I thought little of it.
But then... I noticed something else. If you take a look at my code of the attribute class again. Notice that I am using an attribute on that class as well... And what do you know: named parameters. Working just fine... The AttributeUsage attribute has the exact same configuration: one fixed parameter and two optional parameters. I seem to be able to call them using named parameters just fine, where I cannot call my own attribute constructor with named parameters...
What's going on... Am I losing my mind? Is VS bugged? Or is it infected with a demon?
-
Sep 7th, 2010, 02:21 PM
#2
Re: Optional and named parameters in an Attribute..?
Attributes don't really work in a standard manner here. I want to say they actually predate Optional arguments in VB .NET, but I can't remember if that's right or not. At the very least, I know how it does work.
Peek at AttributeUsage's constructor. See any optional arguments? Nope. So how does it get to use optional arguments?
Attributes are treated specially, that's how. The .NET CLR doesn't actually require that a language support optional parameters, and for a long time C# didn't support them. But it was definitely a boon to have optional parameters for attribute declarations, so a weirdo compiler trick was used instead.
For attribute classes (and only classes used as attributes), here is the convention. Positional "unnamed" parameters are specified as arguments to the constructor of the class. They are expected to have the same name as read-only properties of the class, but allowed to differ by case. Named parameters are not listed in the constructor, but instead listed as read/write properties of the class. When you specify a named parameter, the compiler uses reflection to verify that the parameter name corresponds to a read/write property and generates code to set the value of that property after constructing the attribute object. In this way, languages that don't support optional/named parameters (like C# up to 4.0 but technically no .NET language was *required* to implement them) can still use something like them for attributes.
Thus, when you design an attribute, you have to follow these rules:
- You should only have properties that you intend to correspond to parameters that are set when the attribute is applied.
- Any properties you intend to be required should be read-only and have a corresponding constructor parameter that sets them.
- Any properties you intend to be optional or named should be read/write and not be part of the constructor.
It's a bit messed up, but it's the best they could do in .NET 1.0.
*edit*
Found an MSDN entry that explains it in a sort of roundabout way.
-
Sep 7th, 2010, 03:03 PM
#3
Re: Optional and named parameters in an Attribute..?
I thought named attributes were added to .Net 2.0 for better COM compatibility. Though I didn't see people using them until VS2008 and even then the only ones I'd ever seen used were one those 'Declare Function' calls to an external COM object or an API call to shell.dll
Outside of that the only other time I've ever seen them used are in vb6/vba apps, which is basically COM based anyways.
I guess I've just never really seen a practical use for them in .Net yet.
-
Sep 7th, 2010, 04:26 PM
#4
Re: Optional and named parameters in an Attribute..?
Originally Posted by Sitten Spynne
Attributes don't really work in a standard manner here. I want to say they actually predate Optional arguments in VB .NET, but I can't remember if that's right or not. At the very least, I know how it does work.
Peek at AttributeUsage's constructor. See any optional arguments? Nope. So how does it get to use optional arguments?
Attributes are treated specially, that's how. The .NET CLR doesn't actually require that a language support optional parameters, and for a long time C# didn't support them. But it was definitely a boon to have optional parameters for attribute declarations, so a weirdo compiler trick was used instead.
For attribute classes (and only classes used as attributes), here is the convention. Positional "unnamed" parameters are specified as arguments to the constructor of the class. They are expected to have the same name as read-only properties of the class, but allowed to differ by case. Named parameters are not listed in the constructor, but instead listed as read/write properties of the class. When you specify a named parameter, the compiler uses reflection to verify that the parameter name corresponds to a read/write property and generates code to set the value of that property after constructing the attribute object. In this way, languages that don't support optional/named parameters (like C# up to 4.0 but technically no .NET language was *required* to implement them) can still use something like them for attributes.
Thus, when you design an attribute, you have to follow these rules:
- You should only have properties that you intend to correspond to parameters that are set when the attribute is applied.
- Any properties you intend to be required should be read-only and have a corresponding constructor parameter that sets them.
- Any properties you intend to be optional or named should be read/write and not be part of the constructor.
It's a bit messed up, but it's the best they could do in .NET 1.0.
*edit*
Found an MSDN entry that explains it in a sort of roundabout way.
Thanks. I knew C# didn't support named or optional parameters before .NET 4.0, but I've always thought they were part of VB.NET and hence could be used in Attributes (as long as you were working in VB) as usual. Apparently not. It's getting late so I haven't read all of it yet, I'll do that tomorrow.
Originally Posted by JuggaloBrotha
I thought named attributes were added to .Net 2.0 for better COM compatibility. Though I didn't see people using them until VS2008 and even then the only ones I'd ever seen used were one those 'Declare Function' calls to an external COM object or an API call to shell.dll
Outside of that the only other time I've ever seen them used are in vb6/vba apps, which is basically COM based anyways.
I guess I've just never really seen a practical use for them in .Net yet.
Do you mean named parameters? Or specifically named parameters in attributes? Named parameters are quite common aren't they? I can see great practical use for them, as long as you have a method with a lot of optional parameters. If you have a method with, say, 10 optional parameters and you only want to specify the last one, then without named parameters you could either:
1. Supply the default value for each parameter (so you have to look them up), or
2. Leave it empty, resulting in a method call like
Code:
Me.SomeMethod(,,,,,,,,,"Finally..")
Yeah... not really the syntactic sugar VB promised to have
With named parameters you just do
Code:
Me.SomeMethod(lastValue:="Finally..")
Much easier to read.
And even with normal methods I can see some use for them. If you are calling some method that you don't really know, I find it useful to supply the parameter names just so I can see what the various values do. For example, this:
Code:
Me.CountElements(CountStrings:=True, CountIntegers:=True, CountDates:=False, CountDoubles:=False)
is much easier to read at a glance then
Code:
Me.CountElements(True, True, False, False)
unless you know exactly in which order the parameters are declared.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|