F# under the covers XI -- Literal expressions that aren't; attributes that don't
The problem with being unable to attribute just the getter or setter of a property is resolved at the 1.9.9.9 release (February 2010 CTP).
Consider the following simple C# property
public static FileShare get_Options() | |
{ | |
return (FileShare.Delete | FileShare.Write); | |
} |
This compiles in debug mode to
.method public hidebysig specialname static valuetype [mscorlib]System.IO.FileShare get_Options() cil managed | |
{ | |
.maxstack 1 | |
.locals init ( | |
[0] valuetype [mscorlib]System.IO.FileShare CS$1$0000) | |
L_0000: nop | |
L_0001: ldc.i4.6 | |
L_0002: stloc.0 | |
L_0003: br.s L_0005 | |
L_0005: ldloc.0 | |
L_0006: ret | |
} |
which assigns the literal result -- 6 -- of the expression to the temporary that is then returned. The analogous F# method
static member Options with get() = System.IO.FileShare.Delete ||| System.IO.FileShare.Write | |
// or equivalently | |
static member Options = System.IO.FileShare.Write ||| System.IO.FileShare.Delete |
compiles to IL which preserves the expression to execute only at run time:
.method public specialname static valuetype [mscorlib]System.IO.FileShare get_Options() cil managed | |
{ | |
.maxstack 4 | |
L_0000: nop | |
L_0001: ldc.i4.2 | |
L_0002: ldc.i4.4 | |
L_0003: or | |
L_0004: ret | |
} |
which makes static analysis of the code in the more usually analysed state a rather more complicated business.
Another complicating factor is that while this syntax
[<...>] | |
static member Options = System.IO.FileShare.Write ||| System.IO.FileShare.Delete |
builds, it attaches the attribute (with Method
and Constructor
usage only) to the property as a whole; and not the generated get_Options
method, as in
[...] | |
public static FileShare Options | |
{ | |
get | |
{ | |
return (FileShare.Write | FileShare.Delete); | |
} | |
} |
What I'd like to express, and what I've not found a way to express, is
public static FileShare Options | |
{ | |
[...] | |
get | |
{ | |
return (FileShare.Write | FileShare.Delete); | |
} | |
} |
and MSDN remains opaque on the subject as well.
This is something I could code around, but I can't yet see a clean way of doing to allow separate attributes on the getters and the setters.
Later: The intended syntax for this option is, much as you might expect, this:
static member Options | |
with [<...>] get() = | |
System.IO.FileShare.Write ||| System.IO.FileShare.Delete |
with the necessary insets as shown (to avoid error FS0010: Incomplete structured construct at or before this point in pattern
), however on filing a bug report I got confirmation that it is a known issue with the Beta 2 release (aka October 2009 CTP), that this still decorates the property and not just the getter.
2 comments :
Doesn't this work as expected ?
static member Options with
[< CoverageExemption( Points = 1, Justification = "Code generated is not a Literal") >]get() =
System.IO.FileShare.Write ||| System.IO.FileShare.Delete
Post a Comment