Constructors and keyword arguments

While we're talking about keyword arguments, don't forget that IronPython already gives special treatment to keyword arguments passed into constructors. Additional arguments passed to a constructor by keyword will be used to set properties on the object after it has been created.

i = SomeClass(arg1, X=value)

is the equivalent of i = SomeClass(arg1) i.X = value

.NET supports the latter, through the params keyword in C# and ParamArray in VB.NET, but it doesn't directly support the concept of keyword arguments. Both VB.NET and C# have some concept of optional arguments, though, and IronPython again does magic on our behalf to make them compatible with Python keyword arguments. This means that we can write .NET classes in C# and VB.NET that accept keyword arguments when used from IronPython.

In C# we do this by marking parameters with the DefaultParameterValue attri-bute16 from the System.Runtime.InteropServices namespace. This allows us to specify a value that will be used if the argument is not passed at call time. Interestingly, we can't omit the argument when calling from C#. Although C# allows us to create methods with parameters marked in this way, the language itself doesn't support optional arguments.

This attribute works fine in most cases. One situation it doesn't work in is where the parameter is of a nullable type. A nullable type is a special version of a value type (like an integer or a Boolean, which can't normally be represented by a null) that allows null as a valid value. Under the hood .NET boxes the value, so there are performance implications, but they can be extremely useful where you need null to represent a special value. In C# you declare a variable to be of a nullable type by adding a question mark to the type declaration. A nullable integer is declared with the type declaration int?. Unfortunately we can't use the DefaultParameterValue attribute with nullable types, but we can use the Optional attribute17 instead. This doesn't allow us to specify a default value, but you can always check for null inside the body of your method and supply a default yourself.

16 See http://msdn.microsoft.com/en-us/library/system.runtime.interopservices. defaultparametervalueattribute.aspx.

17 See http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.optionalattribute.aspx.

Listing 14.12 shows a C# class with three static methods. The first takes strings as arguments but provides default values for the last two. The second method takes nul-lable integers as its last two arguments. It prints all three arguments it is called with, but if the second argument is null (omitted), then it is replaced with a default value inside the body of the method.18 The third method allows you to call it with as many arguments as you want, using the params keyword, and prints out how many arguments it is called with.

Was this article helpful?

0 0

Post a comment