Skip to content

Latest commit

 

History

History
53 lines (28 loc) · 2.26 KB

ExtensionPropertyInitializersDesignAndSpec.md

File metadata and controls

53 lines (28 loc) · 2.26 KB

F# 4.0 Speclet: Extension Property Initializers

F# Language User Voice Entry, Pull Request, Commit

Thanks to Edward Paul (@xepaul) for suggesting and contributing the implementation for this feature.

Aim

Allow extension property setters to be used in the initializer syntax at constructor and method calls

Background

F# 2.0+ has always supported both extension properties and "initializer syntax" on method calls, where named properties are given values at object constructor and method calls.

However, setting an extension property in an initializer has not been allowed. This is a needless feature interaction limitation and the combination should be allowed simply for the sake of language hygiene. The combination is also useful in practice.

Design

When analyzing an unassigned named item name = expr in a constructor or method call with return type rty, first look at the intrinsic properties of rty, then look at the extension properties of rty in scope at the point off the call.

Specification

In the F# specification, the section "14.4. Method Application Resolution" currently reads:

If the return type of M, before the application of any type arguments ActualTypeArgs, contains a settable property name, then M is the target.

(The last mention of M on this line in the F# 3.1 spec is a mistake - it should say name).

We adjust the text to clarify that the available settable properties include the property extension members of type, found by consulting the ExtensionsInScope table, as discussed in section 14.1.5.

Examples

For example

C(ExtensionProperty = [1;2;3]) 

Or for example to provide C# “add” pattern like support

type StackLayout with 
    member x.Kids with set (values : UIElement seq) = values |> Seq.iter x.Children.Add 

let layout = StackLayout (Orientation = StackOrientation.Horizontal, 
                          Kids = [Entry(Placeholder = "Username");Entry()])