Full Code of dotnet/csharplang for AI

main 246d64dfbb2f cached
863 files
5.9 MB
1.6M tokens
19 symbols
1 requests
Download .txt
Showing preview only (6,388K chars total). Download the full file or copy to clipboard to get everything.
Repository: dotnet/csharplang
Branch: main
Commit: 246d64dfbb2f
Files: 863
Total size: 5.9 MB

Directory structure:
gitextract_dhtuocpa/

├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   └── ISSUE_TEMPLATE/
│       ├── config.yml
│       ├── docs-feedback.yml
│       └── proposal_template.md
├── .gitignore
├── CODE-OF-CONDUCT.md
├── Communities.md
├── Design-Process.md
├── Language-Version-History.md
├── README.md
├── meetings/
│   ├── 2013/
│   │   ├── LDM-2013-10-07.md
│   │   ├── LDM-2013-10-21.md
│   │   ├── LDM-2013-11-04.md
│   │   ├── LDM-2013-12-16.md
│   │   └── README.md
│   ├── 2014/
│   │   ├── LDM-2014-01-06.md
│   │   ├── LDM-2014-02-03.md
│   │   ├── LDM-2014-02-10.md
│   │   ├── LDM-2014-04-21.md
│   │   ├── LDM-2014-05-07.md
│   │   ├── LDM-2014-05-21.md
│   │   ├── LDM-2014-07-09.md
│   │   ├── LDM-2014-08-27.md
│   │   ├── LDM-2014-09-03.md
│   │   ├── LDM-2014-10-01.md
│   │   ├── LDM-2014-10-15.md
│   │   └── README.md
│   ├── 2015/
│   │   ├── LDM-2015-01-21.md
│   │   ├── LDM-2015-01-28.md
│   │   ├── LDM-2015-02-04.md
│   │   ├── LDM-2015-02-11.md
│   │   ├── LDM-2015-03-04.md
│   │   ├── LDM-2015-03-10-17.md
│   │   ├── LDM-2015-03-18.md
│   │   ├── LDM-2015-03-24.md
│   │   ├── LDM-2015-03-25-Design-Review.md
│   │   ├── LDM-2015-03-25-Notes.md
│   │   ├── LDM-2015-04-01-08.md
│   │   ├── LDM-2015-04-14.md
│   │   ├── LDM-2015-04-15.md
│   │   ├── LDM-2015-04-22-Design-Review.md
│   │   ├── LDM-2015-05-20.md
│   │   ├── LDM-2015-05-25.md
│   │   ├── LDM-2015-07-01.md
│   │   ├── LDM-2015-07-07.md
│   │   ├── LDM-2015-08-18.md
│   │   ├── LDM-2015-09-01.md
│   │   ├── LDM-2015-09-02.md
│   │   ├── LDM-2015-09-08.md
│   │   ├── LDM-2015-10-07-Design-Review.md
│   │   ├── LDM-2015-11-02-Design-Demo.md
│   │   └── README.md
│   ├── 2016/
│   │   ├── LDM-2016-02-29.md
│   │   ├── LDM-2016-04-06.md
│   │   ├── LDM-2016-04-12-22.md
│   │   ├── LDM-2016-05-03-04.md
│   │   ├── LDM-2016-05-10.md
│   │   ├── LDM-2016-07-12.md
│   │   ├── LDM-2016-07-13.md
│   │   ├── LDM-2016-07-15.md
│   │   ├── LDM-2016-08-24.md
│   │   ├── LDM-2016-09-06.md
│   │   ├── LDM-2016-10-18.md
│   │   ├── LDM-2016-10-25-26.md
│   │   ├── LDM-2016-11-01.md
│   │   ├── LDM-2016-11-15.md
│   │   ├── LDM-2016-11-16.md
│   │   ├── LDM-2016-11-30.md
│   │   ├── LDM-2016-12-07-14.md
│   │   └── README.md
│   ├── 2017/
│   │   ├── CLR-2017-03-23.md
│   │   ├── LDM-2017-01-10.md
│   │   ├── LDM-2017-01-11.md
│   │   ├── LDM-2017-01-17.md
│   │   ├── LDM-2017-01-18.md
│   │   ├── LDM-2017-02-14.md
│   │   ├── LDM-2017-02-15.md
│   │   ├── LDM-2017-02-21.md
│   │   ├── LDM-2017-02-22.md
│   │   ├── LDM-2017-02-28.md
│   │   ├── LDM-2017-03-01.md
│   │   ├── LDM-2017-03-07.md
│   │   ├── LDM-2017-03-08.md
│   │   ├── LDM-2017-03-15.md
│   │   ├── LDM-2017-03-21.md
│   │   ├── LDM-2017-03-28.md
│   │   ├── LDM-2017-03-29.md
│   │   ├── LDM-2017-04-05.md
│   │   ├── LDM-2017-04-11.md
│   │   ├── LDM-2017-04-18.md
│   │   ├── LDM-2017-04-19.md
│   │   ├── LDM-2017-05-16.md
│   │   ├── LDM-2017-05-17.md
│   │   ├── LDM-2017-05-26.md
│   │   ├── LDM-2017-05-31.md
│   │   ├── LDM-2017-06-13.md
│   │   ├── LDM-2017-06-14.md
│   │   ├── LDM-2017-06-27.md
│   │   ├── LDM-2017-06-28.md
│   │   ├── LDM-2017-07-05.md
│   │   ├── LDM-2017-07-26.md
│   │   ├── LDM-2017-08-07.md
│   │   ├── LDM-2017-08-09.md
│   │   ├── LDM-2017-08-14.md
│   │   ├── LDM-2017-08-16.md
│   │   ├── LDM-2017-08-21.md
│   │   ├── LDM-2017-08-23.md
│   │   ├── LDM-2017-08-28.md
│   │   ├── LDM-2017-08-30.md
│   │   ├── LDM-2017-09-25.md
│   │   ├── LDM-2017-09-27.md
│   │   ├── LDM-2017-10-02.md
│   │   ├── LDM-2017-10-04.md
│   │   ├── LDM-2017-10-09.md
│   │   ├── LDM-2017-10-11.md
│   │   ├── LDM-2017-10-16.md
│   │   ├── LDM-2017-10-18.md
│   │   ├── LDM-2017-10-25.md
│   │   ├── LDM-2017-11-06.md
│   │   ├── LDM-2017-11-08.md
│   │   ├── LDM-2017-11-20.md
│   │   ├── LDM-2017-11-27.md
│   │   ├── LDM-2017-11-29.md
│   │   ├── LDM-2017-12-04.md
│   │   ├── LDM-2017-12-06.md
│   │   └── README.md
│   ├── 2018/
│   │   ├── LDM-2018-01-03.md
│   │   ├── LDM-2018-01-10.md
│   │   ├── LDM-2018-01-18.md
│   │   ├── LDM-2018-01-22.md
│   │   ├── LDM-2018-01-24.md
│   │   ├── LDM-2018-01-31.md
│   │   ├── LDM-2018-02-05.md
│   │   ├── LDM-2018-02-07.md
│   │   ├── LDM-2018-02-14.md
│   │   ├── LDM-2018-02-21.md
│   │   ├── LDM-2018-02-26.md
│   │   ├── LDM-2018-02-28.md
│   │   ├── LDM-2018-03-14.md
│   │   ├── LDM-2018-03-19.md
│   │   ├── LDM-2018-03-21.md
│   │   ├── LDM-2018-03-28.md
│   │   ├── LDM-2018-04-02.md
│   │   ├── LDM-2018-04-04.md
│   │   ├── LDM-2018-04-25.md
│   │   ├── LDM-2018-04-30.md
│   │   ├── LDM-2018-05-02.md
│   │   ├── LDM-2018-05-14.md
│   │   ├── LDM-2018-05-21.md
│   │   ├── LDM-2018-05-23.md
│   │   ├── LDM-2018-05-30.md
│   │   ├── LDM-2018-06-04.md
│   │   ├── LDM-2018-06-06.md
│   │   ├── LDM-2018-06-25.md
│   │   ├── LDM-2018-07-09.md
│   │   ├── LDM-2018-07-11.md
│   │   ├── LDM-2018-07-16.md
│   │   ├── LDM-2018-08-20.md
│   │   ├── LDM-2018-08-22.md
│   │   ├── LDM-2018-09-05.md
│   │   ├── LDM-2018-09-10.md
│   │   ├── LDM-2018-09-19.md
│   │   ├── LDM-2018-09-24.md
│   │   ├── LDM-2018-09-26.md
│   │   ├── LDM-2018-10-01.md
│   │   ├── LDM-2018-10-03.md
│   │   ├── LDM-2018-10-10.md
│   │   ├── LDM-2018-10-15.md
│   │   ├── LDM-2018-10-17.md
│   │   ├── LDM-2018-10-22.md
│   │   ├── LDM-2018-10-24.md
│   │   ├── LDM-2018-10-29.md
│   │   ├── LDM-2018-10-31.md
│   │   ├── LDM-2018-11-05.md
│   │   ├── LDM-2018-11-14.md
│   │   ├── LDM-2018-11-28.md
│   │   ├── LDM-2018-12-03.md
│   │   ├── LDM-2018-12-05.md
│   │   ├── LDM-2018-12-12.md
│   │   └── README.md
│   ├── 2019/
│   │   ├── LDM-2019-01-07.md
│   │   ├── LDM-2019-01-09.md
│   │   ├── LDM-2019-01-14.md
│   │   ├── LDM-2019-01-16.md
│   │   ├── LDM-2019-01-23.md
│   │   ├── LDM-2019-02-13.md
│   │   ├── LDM-2019-02-20.md
│   │   ├── LDM-2019-02-25.md
│   │   ├── LDM-2019-02-27.md
│   │   ├── LDM-2019-03-04.md
│   │   ├── LDM-2019-03-06.md
│   │   ├── LDM-2019-03-13.md
│   │   ├── LDM-2019-03-19.md
│   │   ├── LDM-2019-03-25.md
│   │   ├── LDM-2019-03-27.md
│   │   ├── LDM-2019-04-01.md
│   │   ├── LDM-2019-04-03.md
│   │   ├── LDM-2019-04-15.md
│   │   ├── LDM-2019-04-22.md
│   │   ├── LDM-2019-04-24.md
│   │   ├── LDM-2019-04-29.md
│   │   ├── LDM-2019-05-13.md
│   │   ├── LDM-2019-05-15.md
│   │   ├── LDM-2019-07-10.md
│   │   ├── LDM-2019-07-17.md
│   │   ├── LDM-2019-07-22.md
│   │   ├── LDM-2019-08-26.md
│   │   ├── LDM-2019-08-28.md
│   │   ├── LDM-2019-09-04.md
│   │   ├── LDM-2019-09-11.md
│   │   ├── LDM-2019-09-16.md
│   │   ├── LDM-2019-09-18.md
│   │   ├── LDM-2019-10-21.md
│   │   ├── LDM-2019-10-23.md
│   │   ├── LDM-2019-10-28.md
│   │   ├── LDM-2019-10-30.md
│   │   ├── LDM-2019-11-11.md
│   │   ├── LDM-2019-11-13.md
│   │   ├── LDM-2019-11-18.md
│   │   ├── LDM-2019-11-25.md
│   │   ├── LDM-2019-12-11.md
│   │   ├── LDM-2019-12-16.md
│   │   ├── LDM-2019-12-18.md
│   │   └── README.md
│   ├── 2020/
│   │   ├── LDM-2020-01-06.md
│   │   ├── LDM-2020-01-08.md
│   │   ├── LDM-2020-01-15.md
│   │   ├── LDM-2020-01-22.md
│   │   ├── LDM-2020-01-29.md
│   │   ├── LDM-2020-02-03.md
│   │   ├── LDM-2020-02-05.md
│   │   ├── LDM-2020-02-10.md
│   │   ├── LDM-2020-02-12.md
│   │   ├── LDM-2020-02-19.md
│   │   ├── LDM-2020-02-24.md
│   │   ├── LDM-2020-02-26.md
│   │   ├── LDM-2020-03-09.md
│   │   ├── LDM-2020-03-23.md
│   │   ├── LDM-2020-03-25.md
│   │   ├── LDM-2020-03-30.md
│   │   ├── LDM-2020-04-01.md
│   │   ├── LDM-2020-04-06.md
│   │   ├── LDM-2020-04-08.md
│   │   ├── LDM-2020-04-13.md
│   │   ├── LDM-2020-04-15.md
│   │   ├── LDM-2020-04-20.md
│   │   ├── LDM-2020-04-27.md
│   │   ├── LDM-2020-05-04.md
│   │   ├── LDM-2020-05-06.md
│   │   ├── LDM-2020-05-11.md
│   │   ├── LDM-2020-05-27.md
│   │   ├── LDM-2020-06-01.md
│   │   ├── LDM-2020-06-10.md
│   │   ├── LDM-2020-06-15.md
│   │   ├── LDM-2020-06-17.md
│   │   ├── LDM-2020-06-22.md
│   │   ├── LDM-2020-06-24.md
│   │   ├── LDM-2020-06-29.md
│   │   ├── LDM-2020-07-01.md
│   │   ├── LDM-2020-07-06.md
│   │   ├── LDM-2020-07-13.md
│   │   ├── LDM-2020-07-20.md
│   │   ├── LDM-2020-07-27.md
│   │   ├── LDM-2020-08-24.md
│   │   ├── LDM-2020-09-09.md
│   │   ├── LDM-2020-09-14.md
│   │   ├── LDM-2020-09-16.md
│   │   ├── LDM-2020-09-23.md
│   │   ├── LDM-2020-09-28.md
│   │   ├── LDM-2020-09-30.md
│   │   ├── LDM-2020-10-05.md
│   │   ├── LDM-2020-10-07.md
│   │   ├── LDM-2020-10-12.md
│   │   ├── LDM-2020-10-14.md
│   │   ├── LDM-2020-10-21.md
│   │   ├── LDM-2020-10-26.md
│   │   ├── LDM-2020-11-04.md
│   │   ├── LDM-2020-11-11.md
│   │   ├── LDM-2020-11-16.md
│   │   ├── LDM-2020-12-02.md
│   │   ├── LDM-2020-12-07.md
│   │   ├── LDM-2020-12-14.md
│   │   ├── LDM-2020-12-16.md
│   │   └── README.md
│   ├── 2021/
│   │   ├── LDM-2021-01-05.md
│   │   ├── LDM-2021-01-11.md
│   │   ├── LDM-2021-01-13.md
│   │   ├── LDM-2021-01-27.md
│   │   ├── LDM-2021-02-03.md
│   │   ├── LDM-2021-02-08.md
│   │   ├── LDM-2021-02-10.md
│   │   ├── LDM-2021-02-22.md
│   │   ├── LDM-2021-02-24.md
│   │   ├── LDM-2021-03-01.md
│   │   ├── LDM-2021-03-03.md
│   │   ├── LDM-2021-03-10.md
│   │   ├── LDM-2021-03-15.md
│   │   ├── LDM-2021-03-24.md
│   │   ├── LDM-2021-03-29.md
│   │   ├── LDM-2021-04-05.md
│   │   ├── LDM-2021-04-07.md
│   │   ├── LDM-2021-04-12.md
│   │   ├── LDM-2021-04-14.md
│   │   ├── LDM-2021-04-19.md
│   │   ├── LDM-2021-04-21.md
│   │   ├── LDM-2021-04-28.md
│   │   ├── LDM-2021-05-03.md
│   │   ├── LDM-2021-05-10.md
│   │   ├── LDM-2021-05-12.md
│   │   ├── LDM-2021-05-17.md
│   │   ├── LDM-2021-05-19.md
│   │   ├── LDM-2021-05-26.md
│   │   ├── LDM-2021-06-02.md
│   │   ├── LDM-2021-06-07.md
│   │   ├── LDM-2021-06-14.md
│   │   ├── LDM-2021-06-21.md
│   │   ├── LDM-2021-07-12.md
│   │   ├── LDM-2021-07-19.md
│   │   ├── LDM-2021-07-26.md
│   │   ├── LDM-2021-08-23.md
│   │   ├── LDM-2021-08-25.md
│   │   ├── LDM-2021-08-30.md
│   │   ├── LDM-2021-09-01.md
│   │   ├── LDM-2021-09-13.md
│   │   ├── LDM-2021-09-15.md
│   │   ├── LDM-2021-09-20.md
│   │   ├── LDM-2021-09-22.md
│   │   ├── LDM-2021-10-13.md
│   │   ├── LDM-2021-10-20.md
│   │   ├── LDM-2021-10-25.md
│   │   ├── LDM-2021-10-27.md
│   │   ├── LDM-2021-11-01.md
│   │   ├── LDM-2021-11-03.md
│   │   ├── LDM-2021-11-10.md
│   │   ├── LDM-2021-12-01.md
│   │   ├── LDM-2021-12-15.md
│   │   └── README.md
│   ├── 2022/
│   │   ├── LDM-2022-01-03.md
│   │   ├── LDM-2022-01-05.md
│   │   ├── LDM-2022-01-12.md
│   │   ├── LDM-2022-01-24.md
│   │   ├── LDM-2022-01-26.md
│   │   ├── LDM-2022-02-07.md
│   │   ├── LDM-2022-02-09.md
│   │   ├── LDM-2022-02-14.md
│   │   ├── LDM-2022-02-16.md
│   │   ├── LDM-2022-02-23.md
│   │   ├── LDM-2022-02-28.md
│   │   ├── LDM-2022-03-02.md
│   │   ├── LDM-2022-03-09.md
│   │   ├── LDM-2022-03-14.md
│   │   ├── LDM-2022-03-21.md
│   │   ├── LDM-2022-03-23.md
│   │   ├── LDM-2022-03-28.md
│   │   ├── LDM-2022-03-30.md
│   │   ├── LDM-2022-04-06.md
│   │   ├── LDM-2022-04-11.md
│   │   ├── LDM-2022-04-13.md
│   │   ├── LDM-2022-04-18.md
│   │   ├── LDM-2022-04-25.md
│   │   ├── LDM-2022-04-27.md
│   │   ├── LDM-2022-05-02.md
│   │   ├── LDM-2022-05-09.md
│   │   ├── LDM-2022-05-11.md
│   │   ├── LDM-2022-05-23.md
│   │   ├── LDM-2022-06-06.md
│   │   ├── LDM-2022-06-29.md
│   │   ├── LDM-2022-07-13.md
│   │   ├── LDM-2022-07-27.md
│   │   ├── LDM-2022-08-03.md
│   │   ├── LDM-2022-08-10.md
│   │   ├── LDM-2022-08-24.md
│   │   ├── LDM-2022-08-31.md
│   │   ├── LDM-2022-09-21.md
│   │   ├── LDM-2022-09-26.md
│   │   ├── LDM-2022-09-28.md
│   │   ├── LDM-2022-10-05.md
│   │   ├── LDM-2022-10-10.md
│   │   ├── LDM-2022-10-12.md
│   │   ├── LDM-2022-10-17.md
│   │   ├── LDM-2022-10-19.md
│   │   ├── LDM-2022-10-26.md
│   │   ├── LDM-2022-11-02.md
│   │   ├── LDM-2022-11-30.md
│   │   ├── LDM-2022-12-14.md
│   │   └── README.md
│   ├── 2023/
│   │   ├── LDM-2023-01-09.md
│   │   ├── LDM-2023-01-11.md
│   │   ├── LDM-2023-01-18.md
│   │   ├── LDM-2023-02-01.md
│   │   ├── LDM-2023-02-15.md
│   │   ├── LDM-2023-02-22.md
│   │   ├── LDM-2023-02-27.md
│   │   ├── LDM-2023-03-01.md
│   │   ├── LDM-2023-03-08.md
│   │   ├── LDM-2023-03-13.md
│   │   ├── LDM-2023-04-03.md
│   │   ├── LDM-2023-04-10.md
│   │   ├── LDM-2023-04-26.md
│   │   ├── LDM-2023-05-01.md
│   │   ├── LDM-2023-05-03.md
│   │   ├── LDM-2023-05-08.md
│   │   ├── LDM-2023-05-15.md
│   │   ├── LDM-2023-05-17.md
│   │   ├── LDM-2023-05-31.md
│   │   ├── LDM-2023-06-05.md
│   │   ├── LDM-2023-06-19.md
│   │   ├── LDM-2023-07-12.md
│   │   ├── LDM-2023-07-17.md
│   │   ├── LDM-2023-07-24.md
│   │   ├── LDM-2023-07-26.md
│   │   ├── LDM-2023-07-31.md
│   │   ├── LDM-2023-08-07.md
│   │   ├── LDM-2023-08-09.md
│   │   ├── LDM-2023-08-14.md
│   │   ├── LDM-2023-08-16.md
│   │   ├── LDM-2023-09-18.md
│   │   ├── LDM-2023-09-20.md
│   │   ├── LDM-2023-09-25.md
│   │   ├── LDM-2023-09-27.md
│   │   ├── LDM-2023-10-02.md
│   │   ├── LDM-2023-10-04.md
│   │   ├── LDM-2023-10-09.md
│   │   ├── LDM-2023-10-11-specification-update.md
│   │   ├── LDM-2023-10-11.md
│   │   ├── LDM-2023-10-16.md
│   │   ├── LDM-2023-11-15.md
│   │   ├── LDM-2023-11-27.md
│   │   ├── LDM-2023-12-04.md
│   │   ├── LDM-2023-12-11.md
│   │   └── README.md
│   ├── 2024/
│   │   ├── LDM-2024-01-08.md
│   │   ├── LDM-2024-01-10.md
│   │   ├── LDM-2024-01-22.md
│   │   ├── LDM-2024-01-29.md
│   │   ├── LDM-2024-01-31.md
│   │   ├── LDM-2024-02-05.md
│   │   ├── LDM-2024-02-07.md
│   │   ├── LDM-2024-02-21.md
│   │   ├── LDM-2024-02-26.md
│   │   ├── LDM-2024-02-28.md
│   │   ├── LDM-2024-03-04.md
│   │   ├── LDM-2024-03-11.md
│   │   ├── LDM-2024-03-27.md
│   │   ├── LDM-2024-04-01.md
│   │   ├── LDM-2024-04-08.md
│   │   ├── LDM-2024-04-15.md
│   │   ├── LDM-2024-04-17.md
│   │   ├── LDM-2024-04-22.md
│   │   ├── LDM-2024-04-24.md
│   │   ├── LDM-2024-05-01.md
│   │   ├── LDM-2024-05-08.md
│   │   ├── LDM-2024-05-13.md
│   │   ├── LDM-2024-05-15-KeyValuePairCorrespondence.md
│   │   ├── LDM-2024-05-15.md
│   │   ├── LDM-2024-06-03.md
│   │   ├── LDM-2024-06-10.md
│   │   ├── LDM-2024-06-12.md
│   │   ├── LDM-2024-06-17.md
│   │   ├── LDM-2024-06-24.md
│   │   ├── LDM-2024-06-26.md
│   │   ├── LDM-2024-07-15-usage-data.md
│   │   ├── LDM-2024-07-15.md
│   │   ├── LDM-2024-07-17.md
│   │   ├── LDM-2024-07-22-ref-struct-interface-examples.md
│   │   ├── LDM-2024-07-22.md
│   │   ├── LDM-2024-07-24.md
│   │   ├── LDM-2024-08-14.md
│   │   ├── LDM-2024-08-19.md
│   │   ├── LDM-2024-08-21.md
│   │   ├── LDM-2024-08-26.md
│   │   ├── LDM-2024-08-28.md
│   │   ├── LDM-2024-09-04.md
│   │   ├── LDM-2024-09-11.md
│   │   ├── LDM-2024-09-18.md
│   │   ├── LDM-2024-09-30.md
│   │   ├── LDM-2024-10-02.md
│   │   ├── LDM-2024-10-07-extension-compat.md
│   │   ├── LDM-2024-10-07.md
│   │   ├── LDM-2024-10-09.md
│   │   ├── LDM-2024-10-14-Enumerable-extension.cs
│   │   ├── LDM-2024-10-14-Enumerable-extensions.cs
│   │   ├── LDM-2024-10-14.md
│   │   ├── LDM-2024-10-16.md
│   │   ├── LDM-2024-10-28.md
│   │   ├── LDM-2024-10-30.md
│   │   ├── LDM-2024-11-04-patterns.md
│   │   ├── LDM-2024-11-04.md
│   │   ├── LDM-2024-11-13.md
│   │   ├── LDM-2024-11-20.md
│   │   ├── LDM-2024-12-04.md
│   │   ├── LDM-2024-12-09.md
│   │   └── README.md
│   ├── 2025/
│   │   ├── LDM-2025-01-06.md
│   │   ├── LDM-2025-01-13.md
│   │   ├── LDM-2025-01-15.md
│   │   ├── LDM-2025-01-22.md
│   │   ├── LDM-2025-02-12.md
│   │   ├── LDM-2025-02-19.md
│   │   ├── LDM-2025-02-24.md
│   │   ├── LDM-2025-02-26.md
│   │   ├── LDM-2025-03-03.md
│   │   ├── LDM-2025-03-05.md
│   │   ├── LDM-2025-03-10.md
│   │   ├── LDM-2025-03-12.md
│   │   ├── LDM-2025-03-17.md
│   │   ├── LDM-2025-03-19.md
│   │   ├── LDM-2025-03-24.md
│   │   ├── LDM-2025-04-02.md
│   │   ├── LDM-2025-04-07.md
│   │   ├── LDM-2025-04-09.md
│   │   ├── LDM-2025-04-14.md
│   │   ├── LDM-2025-04-16.md
│   │   ├── LDM-2025-04-23.md
│   │   ├── LDM-2025-05-05.md
│   │   ├── LDM-2025-05-07.md
│   │   ├── LDM-2025-05-12.md
│   │   ├── LDM-2025-05-28.md
│   │   ├── LDM-2025-06-04.md
│   │   ├── LDM-2025-06-09.md
│   │   ├── LDM-2025-06-11.md
│   │   ├── LDM-2025-06-18.md
│   │   ├── LDM-2025-06-23.md
│   │   ├── LDM-2025-06-25.md
│   │   ├── LDM-2025-06-30.md
│   │   ├── LDM-2025-07-30.md
│   │   ├── LDM-2025-08-13.md
│   │   ├── LDM-2025-08-18.md
│   │   ├── LDM-2025-08-20.md
│   │   ├── LDM-2025-08-27.md
│   │   ├── LDM-2025-09-10.md
│   │   ├── LDM-2025-09-17.md
│   │   ├── LDM-2025-09-24.md
│   │   ├── LDM-2025-09-29.md
│   │   ├── LDM-2025-10-01.md
│   │   ├── LDM-2025-10-13.md
│   │   ├── LDM-2025-10-29.md
│   │   ├── LDM-2025-11-05.md
│   │   ├── LDM-2025-11-12.md
│   │   ├── LDM-2025-12-10.md
│   │   ├── LDM-2025-12-17.md
│   │   └── README.md
│   ├── 2026/
│   │   ├── LDM-2026-01-12.md
│   │   ├── LDM-2026-01-21.md
│   │   ├── LDM-2026-01-26.md
│   │   ├── LDM-2026-02-02.md
│   │   ├── LDM-2026-02-04.md
│   │   ├── LDM-2026-02-09.md
│   │   ├── LDM-2026-02-11.md
│   │   ├── LDM-2026-03-09.md
│   │   └── README.md
│   ├── README.md
│   └── working-groups/
│       ├── collection-literals/
│       │   ├── CL-2022-10-06.md
│       │   ├── CL-2022-10-14.md
│       │   ├── CL-2022-10-21.md
│       │   ├── CL-2023-04-05.md
│       │   ├── CL-2023-04-28.md
│       │   ├── CL-2023-05-10.md
│       │   ├── CL-2023-05-26.md
│       │   ├── CL-2023-06-12.md
│       │   ├── CL-2023-06-26.md
│       │   ├── CL-2023-07-26.md
│       │   ├── CL-2023-08-03.md
│       │   ├── CL-2023-08-10.md
│       │   ├── CL-2023-08-11.md
│       │   ├── CL-2024-01-23.md
│       │   ├── CL-LDM-2023-05-31.md
│       │   ├── CL-LDM-2023-08-14.md
│       │   ├── Compiler-synthesized-types.md
│       │   ├── Core-interface-target-type-proposal.md
│       │   ├── LDM-questions-2023-08-15.md
│       │   ├── collection-expressions-inferred-type.md
│       │   └── collection-expressions-next.md
│       ├── discriminated-unions/
│       │   ├── Case Classes.md
│       │   ├── Closed Enums.md
│       │   ├── Closed Hierarchies.md
│       │   ├── DU-2022-10-19.md
│       │   ├── DU-2022-10-24.md
│       │   ├── DU-2022-10-31.md
│       │   ├── DU-2022-11-07.md
│       │   ├── Nominal Type Unions.md
│       │   ├── Runtime Type Unions.md
│       │   ├── Trade Off Matrix.md
│       │   ├── TypeUnions.md
│       │   ├── Union implementation challenges.md
│       │   ├── allows.md
│       │   ├── brace-syntax.md
│       │   ├── enum-like-unions.md
│       │   ├── extended-enums.md
│       │   ├── original-nominal-type-unions.md
│       │   ├── pre-unification-proposals/
│       │   │   ├── custom-unions.md
│       │   │   ├── nominal-type-unions.md
│       │   │   ├── non-boxing-access-pattern.md
│       │   │   └── union-interfaces.md
│       │   ├── to-nest-or-not-to-nest.md
│       │   ├── type-value-conversion.md
│       │   ├── union-patterns-update.md
│       │   └── union-proposals-overview.md
│       ├── expressions-statements/
│       │   └── ES-2022-11-30.md
│       ├── extensions/
│       │   ├── Compatibility through coexistence between extension types and extension methods.md
│       │   ├── Extension-API-docs.md
│       │   ├── anonymous-extension-declarations.md
│       │   ├── compat-mode-in-extensions.md
│       │   ├── compromise-design-for-extensions.md
│       │   ├── content-based-naming.md
│       │   ├── disambiguation-syntax-examples.md
│       │   ├── extending-extensions-a-guide-to-relaxation.md
│       │   ├── extension-member-disambiguation.md
│       │   ├── extension-members-unified-proposal.md
│       │   ├── extensions-an-evolution-of-extension-methods.md
│       │   ├── extensions-as-static-types.md
│       │   ├── extensions-lookup.md
│       │   ├── extensions_v2.md
│       │   ├── implicit-compatibility-for-ported-extension-methods.md
│       │   ├── metadata-names.md
│       │   ├── rename-to-roles-and-extensions.md
│       │   └── the-design-space-for-extensions.md
│       ├── field-keyword/
│       │   ├── FK-2024-06-26.md
│       │   ├── FK-2024-08-07 Nullability analysis with the `field` keyword.md
│       │   └── FK-2024-08-07.md
│       ├── interceptors/
│       │   ├── IC-2023-03-20.md
│       │   ├── IC-2023-04-04.md
│       │   └── interceptors-issues-2024-01.md
│       ├── nullability-improvements/
│       │   ├── NI-2022-10-24.md
│       │   ├── NI-2022-11-01.md
│       │   ├── NI-2022-11-07.md
│       │   └── NI-2022-11-22.md
│       ├── params-improvements/
│       │   ├── PI-2022-10-25.md
│       │   └── PI-2022-11-03.md
│       ├── ref-improvements/
│       │   ├── REF-2022-11-11.md
│       │   └── ignore-overloads-in-expressions.md
│       ├── roles/
│       │   ├── extension-wg-2024-06-07.md
│       │   ├── extension-wg-2024-06-14.md
│       │   ├── extension-wg-2024-06-21.md
│       │   ├── extensions-2023-02-21.md
│       │   ├── extensions-wg-2023-04-27.md
│       │   ├── extensions-wg-2023-06-07.md
│       │   ├── extensions-wg-2024-03-05.md
│       │   ├── extensions-wg-2024-08-09.md
│       │   ├── roles-2022-11-10.md
│       │   ├── roles-2023-01-23.md
│       │   ├── roles-2023-01-25.md
│       │   └── roles-2023-02-15.md
│       └── unsafe-evolution/
│           └── unsafe-alternative-syntax.md
├── proposals/
│   ├── README.md
│   ├── anonymous-using-declarations.md
│   ├── async-main-update.md
│   ├── block-bodied-switch-expression-arms.md
│   ├── breaking-change-warnings.md
│   ├── case-declarations.md
│   ├── closed-enums.md
│   ├── closed-hierarchies.md
│   ├── collection-expression-arguments.md
│   ├── compound-assignment-in-initializer-and-with.md
│   ├── conditional-operator-access-syntax-refinement.md
│   ├── csharp-10.0/
│   │   ├── GlobalUsingDirective.md
│   │   ├── async-method-builders.md
│   │   ├── caller-argument-expression.md
│   │   ├── constant_interpolated_strings.md
│   │   ├── enhanced-line-directives.md
│   │   ├── extended-property-patterns.md
│   │   ├── file-scoped-namespaces.md
│   │   ├── improved-definite-assignment.md
│   │   ├── improved-interpolated-strings.md
│   │   ├── lambda-improvements.md
│   │   ├── parameterless-struct-constructors.md
│   │   └── record-structs.md
│   ├── csharp-11.0/
│   │   ├── auto-default-structs.md
│   │   ├── checked-user-defined-operators.md
│   │   ├── extended-nameof-scope.md
│   │   ├── file-local-types.md
│   │   ├── generic-attributes.md
│   │   ├── list-patterns.md
│   │   ├── low-level-struct-improvements.md
│   │   ├── new-line-in-interpolation.md
│   │   ├── numeric-intptr.md
│   │   ├── pattern-match-span-of-char-on-string.md
│   │   ├── raw-string-literal.md
│   │   ├── relaxing_shift_operator_requirements.md
│   │   ├── required-members.md
│   │   ├── static-abstracts-in-interfaces.md
│   │   ├── unsigned-right-shift-operator.md
│   │   └── utf8-string-literals.md
│   ├── csharp-12.0/
│   │   ├── collection-expressions.md
│   │   ├── experimental-attribute.md
│   │   ├── inline-arrays.md
│   │   ├── lambda-method-group-defaults.md
│   │   ├── primary-constructors.md
│   │   ├── ref-readonly-parameters.md
│   │   └── using-alias-types.md
│   ├── csharp-13.0/
│   │   ├── collection-expressions-better-conversion.md
│   │   ├── esc-escape-sequence.md
│   │   ├── lock-object.md
│   │   ├── method-group-natural-type-improvements.md
│   │   ├── overload-resolution-priority.md
│   │   ├── params-collections.md
│   │   ├── partial-properties.md
│   │   ├── ref-struct-interfaces.md
│   │   └── ref-unsafe-in-iterators-async.md
│   ├── csharp-14.0/
│   │   ├── extension-operators.md
│   │   ├── extensions.md
│   │   ├── field-keyword.md
│   │   ├── first-class-span-types.md
│   │   ├── ignored-directives.md
│   │   ├── null-conditional-assignment.md
│   │   ├── optional-and-named-parameters-in-expression-trees.md
│   │   ├── partial-events-and-constructors.md
│   │   ├── simple-lambda-parameters-with-modifiers.md
│   │   ├── unbound-generic-types-in-nameof.md
│   │   └── user-defined-compound-assignment.md
│   ├── csharp-6.0/
│   │   ├── empty-params-array.md
│   │   ├── enum-base-type.md
│   │   └── struct-autoprop-init.md
│   ├── csharp-7.0/
│   │   ├── binary-literals.md
│   │   ├── digit-separators.md
│   │   ├── expression-bodied-everything.md
│   │   ├── local-functions.md
│   │   ├── out-var.md
│   │   ├── pattern-matching.md
│   │   ├── ref-locals-returns.md
│   │   ├── task-types.md
│   │   ├── throw-expression.md
│   │   └── tuples.md
│   ├── csharp-7.1/
│   │   ├── README.md
│   │   ├── async-main.md
│   │   ├── generics-pattern-match.md
│   │   ├── infer-tuple-names.md
│   │   └── target-typed-default.md
│   ├── csharp-7.2/
│   │   ├── conditional-ref.md
│   │   ├── leading-separator.md
│   │   ├── non-trailing-named-arguments.md
│   │   ├── private-protected.md
│   │   ├── readonly-ref.md
│   │   ├── readonly-struct.md
│   │   ├── ref-extension-methods.md
│   │   ├── ref-struct-and-span.md
│   │   └── span-safety.md
│   ├── csharp-7.3/
│   │   ├── auto-prop-field-attrs.md
│   │   ├── blittable.md
│   │   ├── enum-delegate-constraints.md
│   │   ├── expression-variables-in-initializers.md
│   │   ├── improved-overload-candidates.md
│   │   ├── indexing-movable-fixed-fields.md
│   │   ├── pattern-based-fixed.md
│   │   ├── ref-local-reassignment.md
│   │   ├── ref-loops.md
│   │   ├── stackalloc-array-initializers.md
│   │   └── tuple-equality.md
│   ├── csharp-8.0/
│   │   ├── README.md
│   │   ├── alternative-interpolated-verbatim.md
│   │   ├── async-streams.md
│   │   ├── async-using.md
│   │   ├── constraints-in-overrides.md
│   │   ├── constructed-unmanaged.md
│   │   ├── default-interface-methods.md
│   │   ├── nested-stackalloc.md
│   │   ├── notnull-constraint.md
│   │   ├── null-coalescing-assignment.md
│   │   ├── nullable-reference-types-specification.md
│   │   ├── nullable-reference-types.md
│   │   ├── obsolete-accessor.md
│   │   ├── patterns.md
│   │   ├── ranges.cs
│   │   ├── ranges.md
│   │   ├── readonly-instance-members.md
│   │   ├── shadowing-in-nested-functions.md
│   │   ├── static-local-functions.md
│   │   ├── unconstrained-null-coalescing.md
│   │   └── using.md
│   ├── csharp-9.0/
│   │   ├── covariant-returns.md
│   │   ├── extending-partial-methods.md
│   │   ├── extension-getenumerator.md
│   │   ├── function-pointers.md
│   │   ├── init.md
│   │   ├── lambda-discard-parameters.md
│   │   ├── local-function-attributes.md
│   │   ├── module-initializers.md
│   │   ├── native-integers.md
│   │   ├── nullable-constructor-analysis.md
│   │   ├── nullable-parameter-default-value-analysis.md
│   │   ├── nullable-reference-types-specification.md
│   │   ├── patterns3.md
│   │   ├── records.md
│   │   ├── skip-localsinit.md
│   │   ├── static-anonymous-functions.md
│   │   ├── target-typed-conditional-expression.md
│   │   ├── target-typed-new.md
│   │   ├── top-level-statements.md
│   │   ├── unconstrained-type-parameter-annotations.md
│   │   └── variance-safety-for-static-interface-members.md
│   ├── deconstruction-in-lambda-parameters.md
│   ├── dictionary-expressions.md
│   ├── enhanced-switch-statements.md
│   ├── expand-ref.md
│   ├── extension-indexers.md
│   ├── fieldof.md
│   ├── final-initializers.md
│   ├── immediately-enumerated-collection-expressions.md
│   ├── inactive/
│   │   ├── README.md
│   │   ├── list-patterns-enumerables.md
│   │   ├── pointer-null-coalescing.md
│   │   └── repeated-attributes.md
│   ├── inference-for-constructor-calls.md
│   ├── inference-for-type-patterns.md
│   ├── interpolated-string-handler-argument-value.md
│   ├── iterators-in-lambdas.md
│   ├── labeled-break-continue.md
│   ├── left-right-join-in-query-expressions.md
│   ├── multiple-using-var-discards.md
│   ├── null-conditional-await.md
│   ├── pattern-variables.md
│   ├── proposal-template.md
│   ├── readonly-parameters.md
│   ├── readonly-setter-calls-on-non-variables.md
│   ├── rejected/
│   │   ├── README.md
│   │   ├── collection-expressions-in-foreach.md
│   │   ├── declaration-expressions.md
│   │   ├── discriminated-unions.md
│   │   ├── fixed-sized-buffers.md
│   │   ├── format.md
│   │   ├── interpolated-string-handler-method-names.md
│   │   ├── intptr-operators.md
│   │   ├── intrinsics.md
│   │   ├── nullable-enhanced-common-type.md
│   │   ├── param-nullchecking.md
│   │   ├── params-span.md
│   │   ├── readonly-locals.md
│   │   ├── records.md
│   │   ├── recordsv2.md
│   │   ├── self-constraint.md
│   │   └── static-delegates.md
│   ├── relaxed-partial-ref-ordering.md
│   ├── speclet-disclaimer.md
│   ├── standard-unions.md
│   ├── target-typed-generic-type-inference.md
│   ├── target-typed-static-member-access.md
│   ├── top-level-members.md
│   ├── type-parameter-inference-from-constraints.md
│   ├── unions.md
│   ├── unsafe-evolution.md
│   └── unsigned-sizeof.md
└── spec/
    ├── LICENSE.md
    ├── README.md
    ├── arrays.md
    ├── attributes.md
    ├── basic-concepts.md
    ├── classes.md
    ├── conversions.md
    ├── delegates.md
    ├── documentation-comments.md
    ├── enums.md
    ├── exceptions.md
    ├── expressions.md
    ├── interfaces.md
    ├── introduction.md
    ├── lexical-structure.md
    ├── namespaces.md
    ├── statements.md
    ├── structs.md
    ├── types.md
    ├── unsafe-code.md
    └── variables.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
* text=auto


================================================
FILE: .github/CODEOWNERS
================================================
*       @dotnet/roslyn-compiler


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Propose a language idea or ask a question
    url: https://github.com/dotnet/csharplang/discussions/new/choose
    about: Starting with discussion is the way to create a new proposal.


================================================
FILE: .github/ISSUE_TEMPLATE/docs-feedback.yml
================================================
name: Learn feedback control.
description: |
  ⛔ This template is hooked into the feedback control on the bottom of every page on the learn.microsoft.com site. It automatically fills in several fields for you. Don't use for other purposes. ⛔
assignees:
  - BillWagner
labels:
  - Area-Speclets
  - untriaged
body:
  - type: markdown
    attributes:
      value: "## Issue information"
  - type: markdown
    attributes:
      value: Select the issue type, and describe the issue in the text box below. Add as much detail as needed to help us resolve the issue.
  - type: dropdown
    id: issue-type
    attributes:
      label: Type of issue
      options:
        - Typo
        - Spec incorrect
        - Spec incomplete
        - Other (describe below)
    validations:
      required: true
  - type: textarea
    id: feedback
    validations:
      required: true
    attributes:
      label: Description
  - type: markdown
    attributes:
      value: "## 🚧 Article information 🚧"
  - type: markdown
    attributes:
      value: "*Don't modify the following fields*. They are automatically filled in for you. Doing so will disconnect your issue from the affected article. *Don't edit them*."
  - type: input
    id: pageUrl
    validations:
      required: true
    attributes:
      label: Page URL
  - type: input
    id: contentSourceUrl
    validations:
      required: true
    attributes:
      label: Content source URL


================================================
FILE: .github/ISSUE_TEMPLATE/proposal_template.md
================================================
---
name: Create a language specification
about: For proposals that have been invited by a team member.
title: "[Proposal]: [FEATURE_NAME]"
---
<!--
Hello, and thanks for your interest in contributing to C#! If you haven't been invited by a language design team member to open an issue, please instead open a discussion marked [draft issue] at https://github.com/dotnet/csharplang/discussions/new and we'll try to give you feedback on how to get to an issue-ready proposal.

This issue should give a very brief description of the feature, with the more complete description and design being contained in the proposal specification. This issue will be used for tracking purposes, and should have enough information to make it obvious what the feature is about for a casual reader.
-->
# FEATURE_NAME

* Specification: Link to a filled out [proposal template](../../proposals/proposal-template.md). If not yet available, link to the PR adding the specification.
* Discussion: Link to the discussion topic for this feature.

## Summary
[summary]: #summary

<!-- Short summary of the feature; the full explanation should be in the checked-in specification. -->

## Design meetings

<!-- Link to design notes that affect this proposal, and describe in one sentence for each what changes they led to. -->


================================================
FILE: .gitignore
================================================
.vscode/*

# Ignore temporary files
~$*
*~


================================================
FILE: CODE-OF-CONDUCT.md
================================================
# Code of Conduct

This project has adopted the code of conduct defined by the Contributor Covenant
to clarify expected behavior in our community.

For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).


================================================
FILE: Communities.md
================================================
**Disclaimer**: This document is maintained by the C# community and not the responsibility of the C# Language Design Team (LDT). Please do not contact the LDT for any errors in this document; however, PRs are welcome. 

**Channels:**

- [Dotnet Discord](https://aka.ms/dotnet-discord-csharp) - github.com/dotnet discord for discussing dotnet repositories (including csharplang).

    [![Chat on Discord](https://discordapp.com/api/guilds/143867839282020352/widget.png)](https://aka.ms/dotnet-discord-csharp)

- [C# Discord](https://aka.ms/csharp-discord) - General C# discussion not limited to the dotnet repositories.

    [![Chat on Discord](https://discordapp.com/api/guilds/102860784329052160/widget.png)](https://aka.ms/csharp-discord)

- IRC - Any discussion related to the C# language up to the application level.

    [![Join the chat at https://www.irccloud.com/invite?channel=%23%23csharp&amp;hostname=irc.freenode.net&amp;port=6697&amp;ssl=1](https://img.shields.io/badge/IRC-%23%23csharp-1e72ff.svg?style=flat)](https://www.irccloud.com/invite?channel=%23%23csharp&amp;hostname=irc.freenode.net&amp;port=6697&amp;ssl=1) 

    Servers: irc.freenode.net, chat.freenode.net
    
    Channel: ##csharp

    [![Join the chat at https://www.irccloud.com/invite?channel=%23c%23&amp;hostname=irc.quakenet.org&amp;port=6697&amp;ssl=1](https://img.shields.io/badge/IRC-%23c%23-1e72ff.svg?style=flat)](https://www.irccloud.com/invite?channel=%23c%23&amp;hostname=irc.quakenet.org&amp;port=6697&amp;ssl=1) 

    Servers: irc.quakenet.org
    
    Channel: #c#

    Recommended IRC Clients: HexChat, mIRC.

**Forums:**

- [Stack Overflow](https://stackoverflow.com)

    Please read [this](https://stackoverflow.com/help/dont-ask) before posting.

- [Reddit](https://www.reddit.com/r/csharp/)

    Please read [this](https://www.reddit.com/r/csharp/comments/3xn6sm/welcome_to_rcsharp_read_this_post_before) before posting.


================================================
FILE: Design-Process.md
================================================
# Language Design Process

The language design process is the steps that a proposal takes throughout its life, going from an initial seed of an idea, to a championed proposal that is being considered
for inclusion in the language, all the way to the final specification representing a feature that has been shipped as part of a .NET release. It is very important to the
language design team that we have a clear process and organization for this, for multiple reasons:

* Our community is very active and vocal on this repo, and we want to make sure that feedback can be heard and impact the design and direction of the language, as well as
  ensuring that the community can follow the state of designs.
* We want to make sure that we are using our design energy effectively, and that we can see the status of previous meetings as we drive a feature to completion.
* We want to be able to look back historically to use previous design decisions to inform new language features, as well as to ensure that when a feature is incorporated into
  the ECMA spec, it captures the full nuances of what was designed.

To achieve these goals, this repository covers the actual proposed text for new language features (often called speclets), notes from language design meetings (called LDM),
intermediate documents being worked on as part of the development of proposals, issues tracking features that we want to include in the C# language (champion issues), and
discussion topics for those features. In order to keep things organized, we keep discussion of proposals to actual discussions; issues are for tracking purposes only. This
policy is changed from previous history in the csharplang repo, so many (most) issues will have some historical discussion in them. However, threaded discussion topics are
better for the types of branching conversations that language features have, so all new discussion will happen in the Discussion forum, rather than on issues.

## Steps of the process

There are a few steps along the path from the seed of an idea all the way to an implemented language feature that is in an official ECMA specification. While much of that
process takes place outside of this repository (https://github.com/dotnet/roslyn for the language feature implementation, https://github.com/dotnet/runtime for supporting
BCL APIs and runtime changes, https://github.com/dotnet/csharpstandard/ for the specification changes, just to name a few), we track the overall implementation of the feature
in this repository, and take the following steps to make understanding the current status easier.

### Proposed feature

New ideas are submitted as [discussions](https://github.com/dotnet/csharplang/discussions). These ideas can be very freeform, though we ask that you search for duplicates
before opening a new discussion, as the most common first comment on new discussions is one or more links to existing discussions that cover the idea. While ideas are welcome,
there is no guarantee that an idea will be adopted into the language; even among things that have been triaged for eventual inclusion in the language, there is more work
than can be done in a single lifetime. In order to move forward, a member of the language design team (LDT) has to decide to "champion" the idea. This is effectively the
LDT member deciding to sponsor the idea, and to bring it forward at a future LDM. Most features do not make it out of this stage.

In order to move to the next stage, there needs to be enough detail to fill out the [proposal template](proposals/proposal-template.md) with at least some amount of detail.
While we do not need exact spec language at this point, there should be enough information that other LDT members can get a general idea of the feature, what areas of the
language it will impact, and where the complicated aspects are likely to be. In order to be triaged as part of an LDM, this template will need to be checked into the repo.

#### Stage Lifecycle

* Starts when a new discussion is opened
* Moves to [Championed feature](#championed-feature) when an LDT member decides to champion
    * For LDT members, see [these instructions](#steps-to-move-a-discussion-to-a-champion-feature) for how to move to the next stage.

### Championed feature

A championed feature is an idea for a C# language feature that an LDT member has decided to sponsor, or "champion", for possible inclusion into C#. You can identify issues
in this category by looking for issues with
[this query](https://github.com/dotnet/csharplang/issues?q=is%3Aissue%20state%3Aopen%20no%3Amilestone%20label%3A%22Proposal%20champion%22), issues with the `Proposal Champion`
label and no milestone. For these issues, one or more LDT members have indicated that they are interested in the idea, but the entire LDM has not met to discuss the idea and
give an official blessing. We try to triage these every few months, though when we start wrapping up a particular release and design time is needed for active questions on
features currently under development, we can lag behind here.

#### Stage Lifecycle

* Starts when an LDT member decides to champion a [proposed feature](#proposed-feature)
* Moves to [rejected feature](#rejected-feature) if rejected at LDM
* Moves to [triaged feature](#triaged-feature) if approved at LDM and assigned to a development milestone

### Triaged feature

A triaged feature is a championed issue that has been approved at LDM for inclusion in a future release of C#. We have quite a few issues in this bucket; they are visible
by looking at any issues labeled `Proposal Champion` that have been assigned to one of the development milestones, `Any Time`, `Backlog`, `Needs More Work`, or `Working Set`.
[This query](https://github.com/dotnet/csharplang/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22Proposal%20champion%22%20(milestone%3ABacklog%20OR%20milestone%3A%22Any%20Time%22%20OR%20milestone%3A%22Needs%20More%20Work%22%20OR%20milestone%3A%22Working%20Set%22%20))
shows these issues. The development milestones mean the following:

* `Working Set` - These are features that are being actively worked on by LDT and/or Roslyn compiler members in some form; whether that's design work behind the scenes,
  active LDMs discussing the topics, or other actions.
* `Backlog` - These are features that have been approved for inclusion in C# at some LDM in the past, but are not currently being actively worked on. These are not open to
  community implementation; they are usually too large or involved to devote LDM time to unless we're willing to make an active effort to get them into the language.
* `Needs More Work` - These are features that have been approved for inclusion in C# at some LDM in the past, but there are currently design aspects or blocking issues that
  prevent active work from proceeding at this point.
* `Any Time` - These are features that have been approved for inclusion in C# at some LDM in the past that are open for community members to contribute to C#. Please do keep
  in mind that the C# compiler team is constrained by resource limits, and will need to devote significant time to helping get even the simplest of features into the language;
  please ask _before_ starting to work on one of these features to make sure the team is currently able to devote that time. Features in this category can be in one of two states,
  denoted by labels on the issue:
    * `Needs Approved Specification` - LDT has approved this in theory, but has not been presented with a precise specification for how the feature will work. Before implementation
      can proceed, a complete specification needs to be created and approved at an LDM.
    * `Needs Implementation` - A specification for this feature has been approved at a previous LDM, and needs to be implemented in the C# compiler.

This state is the one that will consume most of an approved feature's lifecycle, on average. It is not uncommon for a feature that is approved in theory to spend years in the
backlog and/or working set before being implemented.

#### Stage Lifecycle

* Starts when a [championed feature](#championed-feature) is approved at LDM and assigned to a development milestone
* Ends when the feature is [implemented](#implemented-feature) as part of a C# release
    * For LDT members, see [these instructions](#steps-to-move-a-triaged-feature-to-an-implemented-feature) for steps to take when shipping a feature.
* Ends if the feature is reconsidered at an LDM and then [rejected](#rejected-feature)

### Implemented feature

Once a feature has been implemented in the [Roslyn](https://github.com/dotnet/roslyn) C# compiler and been released as part of an official C# release, it is considered implemented.
At this point, it will have a complete speclet available in the [proposals/csharp-\<release version\>](proposals) folder (note that some older C# features, particularly the C# 7.X
and prior features, did not follow this, and have incomplete or non-existent speclets). At this point, the issue will be labeled `Implemented Needs ECMA Specification`, but it will
not be closed until the ECMA-334 specification is updated with the feature. This can take some time; the ECMA-334 committee is working on catching up as fast as they can, but is
several years behind the language implementation.

#### Stage Lifecycle

* Starts when a [triaged feature](#triaged-feature) is shipped as part of a C# release
* Ends when the feature is fully incorporated into a version of the ECMA-334 specification

### ECMA-specified feature

At this point, the feature has been fully incorporated by ECMA-TC49-TG2, the C# standards committee, into the
[official C# ECMA specification](https://github.com/dotnet/csharpstandard/). When this happens, we close the issue as completed, and all development work on the feature is
complete.

#### Stage Lifecycle

* Starts when an [implemented feature](#implemented-feature) is shipped as part of a C# release
* This is the final state for a feature that is included in C#, no further state changes occur

### Rejected feature

When a feature is explicitly considered during an LDM, and the LDT decides as a group to reject it, it moves to this state. At this point, close the champion issue as not planned
and set the milestone to `Likely Never`. It's not impossible for an issue to be pulled back out of this state and included in the language in the future, but generally, this state
means that the feature will never be part of C#.

#### Stage Lifecycle

* Starts when a [championed feature](#championed-feature) is considered at LDM and rejected
* While it is possible that some rejected features end up getting reconsidered, this is generally the final state for language features that are explicitly considered and
  rejected during LDM

## Language Design Team processes

These are various processes and actions taken by LDT members during the development of a feature. Community members should not perform these actions unless invited to do so
by an LDT member.

### Steps to move a [Discussion](#proposed-feature) to a [Champion feature](#championed-feature)

When an LDT member decides to champion a discussion, they take the following steps:

1. Create a new proposal champion issue.
    * If preferred, the LDT member can ask the original proposer to create this issue.
    * Note: it can be easier to create the PR for step 6 first, get that into a ready-to-merge state, and then create the champion issue at that point, depending on the complexity
      of the feature.
    * The champion issue should have a short summary of the feature, but not the full proposal; there should be enough detail to jog the memory and/or get someone interested in reading the full
      specification, but should not have detail that will end up needing to be edited often as a proposal evolves.
2. Assign themselves to the champion issue.
3. Apply the `Proposal Champion` label to the new issue, as well as to the original discussion.
4. Link to the original discussion from the champion issue.
5. Lock the proposal champion issue for comments to ensure that discussion continues in the discussion area, rather than on the champion issue.
6. Fill out and check in a [proposal template](proposals/proposal-template.md) for the feature. Exact spec language is not required, but there should be enough detail to have a
   meaningful triage session.
    * This is also something the LDT member can ask a community member to open a PR for, if they are willing.
    * The filled out proposal should include a link to the champion issue for easy navigation.

### Bringing open questions to LDM

During the course of development of a feature, there are several different types of questions that need to get brought to LDM for answers. The most important overriding factor
for any question is that there is a checked-in commit that contains the question. The document and commit will be linked as part of the notes so that future readers of the notes
can understand the full context in which the question was asked.

#### Alternative proposals, supplemental documentation

As part of the initial design of a feature, a number of different proposals may be brought as part of the design process, either as alternatives to an initial design, or as
supplemental materials to an existing design to help drive conversation in LDM. We want to keep these "supplemental" materials in one place, rather than scattered throughout
the repo as different issues, discussions, and other documents. For such material, they should go in the [working group folder](meetings/working-groups/) for that feature. Not
all features will have such a folder; indeed, most will not. For these documents, please check them in _before_ bringing them to an LDM. The LDM organizer should be able to
link to an exact document, not to a PR. In the event the proposer wants to solicit input before LDM, they can leave the PR open until a day or two before LDM; in such a case the
LDM organizer may decide to link to the PR in the schedule instead of a specific document. However, the PR must be merged before LDM.

#### Specific implementation questions

During the implementation process, we will often come up with specific scenarios that need to be brought to an LDM and discussed. These questions should be placed in the proposal
specification, in an `Open Questions` section below the main specification text. Each question should have a _linkable_ header, such that the notes that go over the question can
link to the exact question being asked. For these questions, please check them in _before_ bringing them to an LDM. The LDM organizer should be able to link to a specific heading
in a specific document, not to a PR. In the event the questioner wants to solicit input before LDM, they can leave the PR open until a day or two before LDM; in such a case the
LDM organizer may decide to link to the PR in the schedule instead of a specific document. However, the PR must be merged before LDM.

Once a question has been answered, the specification should be updated to include any changes required, and the question should be removed. We link to exact commits in the notes
to ensure that questions can still be found, while keep speclets neat and free of potentially confusing syntax examples that may be rejected at LDM.

#### Proposed specification updates

Sometimes during implementation, a specification needs to be updated. These updates are often best viewed by looking at a PR diff; however, PRs present a problem for historical
recording keeping. While GitHub does keep around commits that were only ever part of a PR (either because the PR was closed, or because it was squashed/rebased), reusing a PR
across multiple LDM sessions can make it difficult to understand the exact state of the PR when it was reviewed by LDM. Whenever possible, do not reuse PRs between multiple LDM
sessions. When a PR is reviewed by LDM, either close or merge it, and make a new PR for the next LDM to pick up where it left off. This is a guideline, not a rule; there will be
times this cannot happen for whatever reason. But the following rules _must_ be followed:

1. Do not force push over commits that have been reviewed by LDM.
2. When scheduling your topic for LDM, please use GitHub commit URL or commit range URL. The PR link can be included as well, but the commit (range) is required for inclusion in
   the notes. The LDM organizer should be able to link to exactly what will be reviewed in the LDM session.

### Steps to move a [triaged feature](#triaged-feature) to an [implemented feature](#implemented-feature)

Once a feature has been implemented and has or soon will be shipped, take the following steps (these are usually done in bulk when a release nears):

1. If a folder for the C# release does not exist yet, create it.
2. Move the specification for the feature into that folder and review relative links it contains.
3. Update the champion issue as follows:
   1. Update the specification link to point at the new location.
   2. Update the milestone of the issue to be the C# release it has shipped/will ship in, creating it if it doesn't exist.
   3. Add the version of .NET and VS it will/did ship in to the issue title.
        * As an example, `[Proposal]: Params Collections` became `[Proposal]: Params Collections (VS 17.10, .NET 9)`
   4. Add the `Implemented Needs ECMA Spec` label to the issue.
4. Add the feature to the [language version history](Language-Version-History.md) document.

### Publishing notes (for the LDM notetaker)

When publishing a set of notes, take the following steps:

1. Put the notes in the appropriate `meetings/<year>` folder. Notes should follow the `LDM-<year>-<month>-<date>.md` format.
   1. Any supplemental documents for the meeting are also included here with the same prefix to ensure good sorting.
   2. Include an agenda at the top with document-relative links to each section corresponding to the topics discussed during LDM.
   3. Include both the champion issue and the reviewed specification for a given topic.
   4. Ensure there are two spaces at the end of lines that do not have an extra line break (such as between entries for the champion issue and specification).
   5. All links should be permalinks (rather than branch links). If you press "y" on the page, the URL in the browser will update to the permalink.
2. Update the `meetings/<year>/README.md` to:
   1. Move the date into the `C# Language Design Notes for <year>` section
   2. Update the agenda to match what is in the meeting notes, with the document-relative links removed.
   3. Include a link to the notes. This format is usually `[C# Language Design Meeting for <month> <day>, <year>](absolute-note-link)` (use the branch link here).
   4. When entering the questions discussed, use the question rather than the outcome.
   5. If a topic was not discussed during LDM, or not fully finished, move the topic line back to `Schedule ASAP`.
3. Commit the updates. Prefer using spelled out dates (ie, January 1st, 1970), rather than abbreviations, to avoid confusion.
4. Update the champion issues of discussed topics with a link to the notes. Prefer using an exact link to the heading for that set of notes.
5. Create a discussion for the new notes. The title format is `LDM Notes for <month> <day>, <year>`. Set the category to `LDM Notes`.
   1. The discussion should link to the full notes, and copy the agenda from the README.
6. Post the discussion to various communities to let people know the notes are up; at a minimum, to the C# LDM teams chat. We often post to
   discord as well, but that is dependent on people being who are on discord not being on vacation.


================================================
FILE: Language-Version-History.md
================================================
Features Added in C# Language Versions
====================

# C# 14.0 - .NET 10 and Visual Studio 2026 version 18.0
- [Extension methods and properties](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/extensions.md): allows extending an existing type with instance or static methods and properties.
- [Extension operators](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/extension-operators.md): allows extending an existing type with operators.
- [`field` keyword in properties](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/field-keyword.md): `field` allows access to the property's backing field without having to declare it.
- [Partial events and constructors](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/partial-events-and-constructors.md): allows the partial modifier on events and constructors to separate declaration and implementation parts.
- [User-defined compound assignment operators](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/user-defined-compound-assignment.md): allow user types to customize behavior of compound assignment operators in a way that the target of the assignment is modified in-place (`public void operator +=(int x)`).
- [First-class `Span` types](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/first-class-span-types.md): streamlines usage of `Span`-based APIs by improving type inference and overload resolution.
- [Null-conditional assignment](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/null-conditional-assignment.md): permits assignment to occur conditionally within a `a?.b` or `a?[b]` expression (`a?.b = c`).
- [Unbound generic types in `nameof`](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/unbound-generic-types-in-nameof.md): relaxes some restrictions on usage of generic types inside `nameof` (`nameof(List<>)`).
- [Simple lambda parameters with modifiers](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/simple-lambda-parameters-with-modifiers.md): allows lambda parameters to be declared with modifiers without requiring their types (`(ref entry) => ...`).
- [Ignored directives](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/ignored-directives.md): add `#:` directive prefix to be used by `dotnet run app.cs` tooling but ignored by the language.
- [Optional and named arguments in `Expression` trees](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-14.0/optional-and-named-parameters-in-expression-trees.md): relaxes some restrictions on `Expression` trees (`Expression<...> e = (a, i) => a.Contains(i, comparer: null);`).

# C# 13.0 - .NET 9 and Visual Studio 2022 version 17.12
- [ESC escape sequence](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/esc-escape-sequence.md): introduces the `\e` escape sequence to represent the ESCAPE/ESC character (U+001B).
- [Method group natural type improvements](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/method-group-natural-type-improvements.md): look scope-by-scope and prune inapplicable candidates early when determining the natural type of a method group.
- [`Lock` object](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/lock-object.md): allow performing a `lock` on `System.Threading.Lock` instances.
- Implicit indexer access in object initializers: allows indexers in object initializers to use implicit Index/Range indexers (`new C { [^1] = 2 }`).
- [`params` collections](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/params-collections.md): extends `params` support to collection types (`void M(params ReadOnlySpan<int> s)`).
- [`ref`/`unsafe` in iterators/async](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/ref-unsafe-in-iterators-async.md): allows using `ref`/`ref struct` locals and `unsafe` blocks in iterators and async methods between suspension points.
- [`ref struct` interfaces](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/ref-struct-interfaces.md): allows `ref struct` types to implement interfaces and introduces the `allows ref struct` constraint.
- [Overload resolution priority](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/overload-resolution-priority.md): allows API authors to adjust the relative priority of overloads within a type using `System.Runtime.CompilerServices.OverloadResolutionPriority`.
- [Partial properties](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/partial-properties.md): allows splitting a property into multiple parts using the `partial` modifier.
- [Better conversion from collection expression element](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-13.0/collection-expressions-better-conversion.md): improves overload resolution to account for the element type of collection expressions.

# C# 12.0 - .NET 8 and Visual Studio 2022 version 17.8

- [Collection expressions](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/collection-expressions.md): provides a uniform and efficient way of creating collections using collection-like types (`List<int> list = [1, 2, 3];`)
- [Primary Constructors](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/primary-constructors.md): helps reduce field and constructor boilerplate (`class Point(int x, int y);`)
- [Inline Arrays](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/inline-arrays.md): provides a general-purpose and safe mechanism for declaring arrays using the `[InlineArray(size)]` attribute.
- [Using aliases for any type](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/using-alias-types.md): relaxes many restrictions on `using` alias declarations, allowing built-in types, tuple types, pointer types, array types (`using Point = (int x, int y);`)
- [Ref readonly parameters](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/ref-readonly-parameters.md): `ref readonly` parameters mandate that arguments are passed by reference instead of potentially copied, can’t be modified, and warn if a temporary variable must be created.
- [Nameof accessing instance members](https://github.com/dotnet/csharplang/issues/4037): relaxes some restrictions on usage of instance members inside `nameof` (`nameof(field.ToString)`)
- [Lambda optional parameters](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-12.0/lambda-method-group-defaults.md): allows lambda parameters to declare default values (`(int i = 42) => { }`)

# C# 11.0 - .NET 7 and Visual Studio 2022 version 17.4

- [Raw string literals](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/raw-string-literal.md): introduces a string literal where the content never needs escaping (`var json = """{ "summary": "text" }""";` or `var json = $$"""{ "summary": "text", "length": {{length}} }""";`).
- [UTF-8 string literals](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/utf8-string-literals.md): UTF-8 string literals with the `u8` suffix (`ReadOnlySpan<byte> s = "hello"u8;`)
- [Pattern match `Span<char>` on a constant string](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/pattern-match-span-of-char-on-string.md): an input value of type `Span<char>` or `ReadonlySpan<char>` can be matched with a constant string pattern (`span is "123"`).
- [Newlines in interpolations](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/new-line-in-interpolation.md): allows newline characters in single-line interpolated strings.
- [List patterns](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/list-patterns.md): allows matching indexable types (`list is [1, 2, ..]`).
- [File-local types](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/file-local-types.md): introduces the `file` type modifier (`file class C { ... }`).
- [Ref fields](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/low-level-struct-improvements.md): allows `ref` field declarations in a `ref struct` (`ref struct S { ref int field; ... }`), introduces `scoped` modifier and `[UnscopedRef]` attribute.
- [Required members](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/required-members.md): introduces the `required` field and property modifier and `[SetsRequiredMembers]` attribute.
- [Static abstract members in interfaces](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/static-abstracts-in-interfaces.md): allows an interface to specify abstract static members.
- [Unsigned right-shift operator](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/unsigned-right-shift-operator.md): introduces the `>>>` operator and `>>>=`.
- [`checked` user-defined operators](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/checked-user-defined-operators.md): numeric and conversion operators support defining `checked` variants (`public static Int128 operator checked +(Int128 lhs, Int128 rhs) { ... }`).
- [Relaxing shift operator requirements](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/relaxing_shift_operator_requirements.md): the right-hand-side operand of a shift operator is no longer restricted to only be `int`
- [Numeric IntPtr](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/numeric-intptr.md): `nint`/`nuint` become simple types aliasing `System.IntPtr`/`System.UIntPtr`.
- [Auto-default structs](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/auto-default-structs.md): struct constructors automatically default fields that are not explicitly assigned.
- [Generic attributes](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/generic-attributes.md): allows attributes to be generic (`[MyAttribute<int>]`).
- [Extended `nameof` scope in attributes](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/extended-nameof-scope.md): allows `nameof(parameter)` inside an attribute on a method or parameter (`[MyAttribute(nameof(parameter))] void M(int parameter) { }`).

# C# 10.0 - .NET 6 and Visual Studio 2022 version 17.0

- [Record structs](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-10.0/record-structs.md) (`record struct Point(int X, int Y);`, `var newPoint = point with { X = 100 };`).
- [With expression](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/record-structs.md#allow-with-expression-on-structs) on structs and anonymous types.
- [Global using directives](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-10.0/GlobalUsingDirective.md): `global using` directives avoid repeating the same `using` directives across many files in your program.
- [Improved definite assignment](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/improved-definite-assignment.md): definite assignment and nullability analysis better handle common patterns such as `dictionary?.TryGetValue(key, out value) == true`.
- [Constant interpolated strings](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/constant_interpolated_strings.md): interpolated strings composed of constants are themselves constants.
- [Extended property patterns](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/extended-property-patterns.md): property patterns allow accessing nested members (`if (e is MethodCallExpression { Method.Name: "MethodName" })`).
- [Sealed record ToString](https://github.com/dotnet/csharplang/issues/4174): a record can inherit a base record with a sealed `ToString`.
- [Incremental source generators](https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.md): improve the source generation experience in large projects by breaking down the source generation pipeline and caching intermediate results.
- [Mixed deconstructions](https://github.com/dotnet/csharplang/issues/125): deconstruction-assignments and deconstruction-declarations can be blended together (`(existingLocal, var declaredLocal) = expression`).
- [Method-level AsyncMethodBuilder](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/async-method-builders.md): the AsyncMethodBuilder used to compile an `async` method can be overridden locally.
- [#line span directive](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/enhanced-line-directives.md): allow source generators like Razor fine-grained control of the line mapping with `#line` directives that specify the destination span (`#line (startLine, startChar) - (endLine, endChar) charOffset "fileName"`).
- [Lambda improvements](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/lambda-improvements.md): attributes and return types are allowed on lambdas; lambdas and method groups have a natural delegate type (`var f = short () => 1;`).
- [Interpolated string handlers](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/improved-interpolated-strings.md): interpolated string handler types allow efficient formatting of interpolated strings in assignments and invocations.
- [File-scoped namespaces](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/file-scoped-namespaces.md): files with a single namespace don't need extra braces or indentation (`namespace X.Y.Z;`).
- [Parameterless struct constructors](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/parameterless-struct-constructors.md): support parameterless constructors and instance field initializers for struct types.
- [CallerArgumentExpression](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-10.0/caller-argument-expression.md): this attribute allows capturing the expressions passed to a method as strings.

# C# 9.0 - .NET 5 and Visual Studio 2019 version 16.8 
- [Records](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/records.md) and `with` expressions: succinctly declare reference types with value semantics (`record Point(int X, int Y);`, `var newPoint = point with { X = 100 };`).
- [Init-only setters](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/init.md): init-only properties can be set during object creation (`int Property { get; init; }`).
- [Top-level statements](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/top-level-statements.md): the entry point logic of a program can be written without declaring an explicit type or `Main` method.
- [Pattern matching enhancements](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/patterns3.md): relational patterns (`is < 30`), combinator patterns (`is >= 0 and <= 100`, `case 3 or 4:`, `is not null`), parenthesized patterns (`is int and (< 0 or > 100)`), type patterns (`case Type:`).
- [Native sized integers](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/native-integers.md): the numeric types `nint` and `nuint` match the platform memory size.
- [Function pointers](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/function-pointers.md): enable high-performance code leveraging IL instructions `ldftn` and `calli` (`delegate* <int, void> local;`)
- [Suppress emitting `localsinit` flag](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/skip-localsinit.md): attributing a method with `[SkipLocalsInit]` will suppress emitting the `localsinit` flag to reduce cost of zero-initialization.
- [Target-typed new expressions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/target-typed-new.md): `Point p = new(42, 43);`.
- [Static anonymous functions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/static-anonymous-functions.md): ensure that anonymous functions don't capture `this` or local variables (`static () => { ... };`).
- [Target-typed conditional expressions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/target-typed-conditional-expression.md): conditional expressions which lack a natural type can be target-typed (`int? x = b ? 1 : null;`).
- [Covariant return types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/covariant-returns.md): a method override on reference types can declare a more derived return type.
- [Lambda discard parameters](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/lambda-discard-parameters.md): multiple parameters `_` appearing in a lambda are allowed and are discards.
- [Attributes on local functions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/local-function-attributes.md).
- [Module initializers](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/module-initializers.md): a method attributed with `[ModuleInitializer]` will be executed before any other code in the assembly.
- [Extension `GetEnumerator`](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/extension-getenumerator.md): an extension `GetEnumerator` method can be used in a `foreach`.
- [Partial methods with returned values](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/extending-partial-methods.md): partial methods can have any accessibility, return a type other than `void` and use `out` parameters, but must be implemented.
- [Source Generators](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/)

# C# 8.0 - .NET Core 3.0 and Visual Studio 2019 version 16.3 
- [Nullable reference types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/nullable-reference-types-specification.md): express nullability intent on reference types with `?`, `notnull` constraint and annotations attributes in APIs, the compiler will use those to try and detect possible `null` values being dereferenced or passed to unsuitable APIs.
- [Default interface members](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/default-interface-methods.md): interfaces can now have members with default implementations, as well as static/private/protected/internal members except for state (ie. no fields).
- [Recursive patterns](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/patterns.md): positional and property patterns allow testing deeper into an object, and switch expressions allow for testing multiple patterns and producing corresponding results in a compact fashion.
- [Async streams](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/async-streams.md): `await foreach` and `await using` allow for asynchronous enumeration and disposal of `IAsyncEnumerable<T>` collections and `IAsyncDisposable` resources, and async-iterator methods allow convenient implementation of such asynchronous streams.
- [Enhanced using](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/using.md): a `using` declaration is added with an implicit scope and `using` statements and declarations allow disposal of `ref` structs using a pattern.
- [Ranges and indexes](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/ranges.md): the `i..j` syntax allows constructing `System.Range` instances, the `^k` syntax allows constructing `System.Index` instances, and those can be used to index/slice collections.
- [Null-coalescing assignment](https://github.com/dotnet/csharplang/issues/34): `??=` allows conditionally assigning when the value is null.
- [Static local functions](https://github.com/dotnet/csharplang/issues/1565): local functions modified with `static` cannot capture `this` or local variables, and local function parameters now shadow locals in parent scopes.
- [Unmanaged generic structs](https://github.com/dotnet/csharplang/issues/1744): generic struct types that only have unmanaged fields are now considered unmanaged (ie. they satisfy the `unmanaged` constraint).
- [Readonly members](https://github.com/dotnet/csharplang/issues/1710): individual members can now be marked as `readonly` to indicate and enforce that they do not modify instance state.
- [Stackalloc in nested contexts](https://github.com/dotnet/csharplang/issues/1412): `stackalloc` expressions are now allowed in more expression contexts.
- [Alternative interpolated verbatim strings](https://github.com/dotnet/csharplang/issues/1630): `@$"..."` strings are recognized as interpolated verbatim strings just like `$@"..."`.
- [Obsolete on property accessors](https://github.com/dotnet/csharplang/issues/2152): property accessors can now be individually marked as obsolete.
- [Permit `t is null` on unconstrained type parameter](https://github.com/dotnet/csharplang/issues/1284)

# C# 7.3 - Visual Studio 2017 version 15.7
- `System.Enum`, `System.Delegate` and [`unmanaged`](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/blittable.md) constraints.
- [Ref local re-assignment](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/ref-local-reassignment.md): Ref locals and ref parameters can now be reassigned with the ref assignment operator (`= ref`).
- [Stackalloc initializers](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/stackalloc-array-initializers.md): Stack-allocated arrays can now be initialized, e.g. `Span<int> x = stackalloc[] { 1, 2, 3 };`.
- [Indexing movable fixed buffers](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/indexing-movable-fixed-fields.md): Fixed buffers can be indexed into without first being pinned.
- [Custom `fixed` statement](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/pattern-based-fixed.md): Types that implement a suitable `GetPinnableReference` can be used in a `fixed` statement.
- [Improved overload candidates](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/improved-overload-candidates.md): Some overload resolution candidates can be ruled out early, thus reducing ambiguities.
- [Expression variables in initializers and queries](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/expression-variables-in-initializers.md): Expression variables like `out var` and pattern variables are allowed in field initializers, constructor initializers and LINQ queries.
-	[Tuple comparison](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/tuple-equality.md): Tuples can now be compared with `==` and `!=`.
-	[Attributes on backing fields](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.3/auto-prop-field-attrs.md): Allows `[field: …]` attributes on an auto-implemented property to target its backing field.

# [C# 7.2](https://blogs.msdn.microsoft.com/dotnet/2017/11/15/welcome-to-c-7-2-and-span/) - Visual Studio 2017 version 15.5
- [Span and ref-like types](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/span-safety.md)
- [In parameters and readonly references](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/readonly-ref.md)
- [Ref conditional](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/conditional-ref.md)
- [Non-trailing named arguments](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/non-trailing-named-arguments.md)
- [Private protected accessibility](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/private-protected.md)
- [Digit separator after base specifier](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/leading-separator.md)

# [C# 7.1](https://blogs.msdn.microsoft.com/dotnet/2017/10/31/welcome-to-c-7-1/) - Visual Studio 2017 version 15.3
- [Async main](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/async-main.md)
- [Default expressions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/target-typed-default.md)
- [Reference assemblies](https://github.com/dotnet/roslyn/blob/master/docs/features/refout.md)
- [Inferred tuple element names](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/infer-tuple-names.md)
- [Pattern-matching with generics](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.1/generics-pattern-match.md)

# [C# 7.0](https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/) - Visual Studio 2017
- [Out variables](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/out-var.md)
- [Pattern matching](https://github.com/dotnet/csharplang/blob/main/proposals/csharp-7.0/pattern-matching.md)
- [Tuples](https://github.com/dotnet/roslyn/blob/master/docs/features/tuples.md)
- [Deconstruction](https://github.com/dotnet/roslyn/blob/master/docs/features/deconstruction.md)
- [Discards](https://github.com/dotnet/roslyn/blob/master/docs/features/discards.md)
- [Local Functions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/local-functions.md)
- [Binary Literals](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/binary-literals.md)
- [Digit Separators](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/digit-separators.md)
- [Ref returns and locals](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/ref-returns)
- [Generalized async return types](https://github.com/dotnet/roslyn/blob/master/docs/features/task-types.md)
- [More expression-bodied members](https://docs.microsoft.com/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members)
- [Throw expressions](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.0/throw-expression.md)

# [C# 6](https://github.com/dotnet/roslyn/blob/master/docs/wiki/New-Language-Features-in-C%23-6.md) - Visual Studio 2015
- [Draft Specification online](https://github.com/dotnet/csharpstandard/blob/draft-v6/standard/README.md)
- Compiler-as-a-service (Roslyn)
- [Import of static type members into namespace](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-static)
- [Exception filters](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/when)
- Await in catch/finally blocks
- Auto property initializers
- Default values for getter-only properties
- [Expression-bodied members](https://docs.microsoft.com/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members)
- Null propagator (null-conditional operator, succinct null checking)
- [String interpolation](https://docs.microsoft.com/dotnet/csharp/language-reference/tokens/interpolated)
- [nameof operator](https://docs.microsoft.com/dotnet/csharp/language-reference/operators/nameof)
- Dictionary initializer

# [C# 5](https://blogs.msdn.microsoft.com/mvpawardprogram/2012/03/26/an-introduction-to-new-features-in-c-5-0/) - Visual Studio 2012
- [Asynchronous methods](https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/async/)
- [Caller info attributes](https://docs.microsoft.com/dotnet/csharp/language-reference/attributes/caller-information)
- foreach loop was changed to generates a new loop variable rather than closing over the same variable every time

# [C# 4](https://msdn.microsoft.com/magazine/ff796223.aspx) - Visual Studio 2010
- [Dynamic binding](https://docs.microsoft.com/dotnet/csharp/programming-guide/types/using-type-dynamic)
- [Named and optional arguments](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments)
- [Co- and Contra-variance for generic delegates and interfaces](https://docs.microsoft.com/dotnet/standard/generics/covariance-and-contravariance)
- [Embedded interop types ("NoPIA")](https://docs.microsoft.com/dotnet/framework/interop/type-equivalence-and-embedded-interop-types)

# [C# 3](https://msdn.microsoft.com/library/bb308966.aspx) - Visual Studio 2008
- [Implicitly typed local variables](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/implicitly-typed-local-variables)
- [Object and collection initializers](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/object-and-collection-initializers)
- [Auto-Implemented properties](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/auto-implemented-properties)
- [Anonymous types](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/anonymous-types)
- [Extension methods](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/extension-methods)
- [Query expressions, a.k.a LINQ (Language Integrated Query)](https://docs.microsoft.com/dotnet/csharp/linq/query-expression-basics)
- [Lambda expression](https://docs.microsoft.com/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions)
- [Expression trees](https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/expression-trees/)
- [Partial methods](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/partial-method)
- [Lock statement](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/lock-statement)

# [C# 2](https://msdn.microsoft.com/library/7cz8t42e(v=vs.80).aspx) - Visual Studio 2005
- [Generics](https://docs.microsoft.com/dotnet/csharp/programming-guide/generics/)
- [Partial types](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/partial-type)
- [Anonymous methods](https://docs.microsoft.com/dotnet/csharp/programming-guide/statements-expressions-operators/anonymous-functions)
- [Iterators, a.k.a yield statement](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/yield)
- [Nullable types](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/nullable-value-types)
- Getter/setter separate accessibility
- Method group conversions (delegates)
- [Static classes](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/static-classes-and-static-class-members)
- Delegate inference
- Type and namespace aliases
- [Covariance and contravariance](https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/covariance-contravariance/)

# [C# 1.2](https://docs.microsoft.com/dotnet/csharp/whats-new/csharp-version-history#c-version-12) - Visual Studio .NET 2003
- Dispose in foreach
- foreach over string specialization

# [C# 1.0](https://en.wikipedia.org/wiki/Microsoft_Visual_Studio#.NET_.282002.29) - Visual Studio .NET 2002
- [Classes](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/classes)
- [Structs](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/struct)
- [Enums](https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/enum)
- [Interfaces](https://docs.microsoft.com/dotnet/csharp/programming-guide/interfaces/)
- [Events](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/event)
- [Operator overloading](https://docs.microsoft.com/dotnet/csharp/language-reference/operators/operator-overloading)
- [User-defined conversion operators](https://docs.microsoft.com/dotnet/csharp/language-reference/operators/user-defined-conversion-operators)
- [Properties](https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/properties)
- [Indexers](https://docs.microsoft.com/dotnet/csharp/programming-guide/indexers/)
- Output parameters ([out](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/out) and [ref](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/ref))
- [`params` arrays](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/params)
- [Delegates](https://docs.microsoft.com/dotnet/csharp/programming-guide/delegates/)
- Expressions
- [using statement](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/using-statement)
- [goto statement](https://docs.microsoft.com/dotnet/csharp/language-reference/keywords/goto)
- [Preprocessor directives](https://docs.microsoft.com/dotnet/csharp/language-reference/preprocessor-directives/)
- [Unsafe code and pointers](https://docs.microsoft.com/dotnet/csharp/programming-guide/unsafe-code-pointers/)
- [Attributes](https://docs.microsoft.com/dotnet/csharp/programming-guide/concepts/attributes/)
- Literals
- [Verbatim identifier](https://docs.microsoft.com/dotnet/csharp/language-reference/tokens/verbatim)
- Unsigned integer types
- [Boxing and unboxing](https://docs.microsoft.com/dotnet/csharp/programming-guide/types/boxing-and-unboxing)


================================================
FILE: README.md
================================================
# C# Language Design

[![Join the chat at https://gitter.im/dotnet/csharplang](https://badges.gitter.im/dotnet/csharplang.svg)](https://gitter.im/dotnet/csharplang?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Chat on Discord](https://discordapp.com/api/guilds/143867839282020352/widget.png)](https://aka.ms/dotnet-discord-csharp)

Welcome to the official repo for C# language design. This is where new C# language features are developed, adopted and specified.

C# is designed by the C# Language Design Team (LDT) in close coordination with the [Roslyn](https://github.com/dotnet/roslyn) project, which implements the language.

You can find:

- Active C# language feature proposals in the [proposals folder](proposals)
- Notes from C# language design meetings in the [meetings folder](meetings)
- Summary of the [language version history here](Language-Version-History.md).

If you discover bugs or deficiencies in the above, please leave an issue to raise them, or even better: a pull request to fix them.

For *new feature proposals*, however, please raise them for [discussion](https://github.com/dotnet/csharplang/labels/Discussion), and *only* submit a proposal as an issue or pull request if invited to do so by a member of the Language Design Team (a "champion").

The complete design process is described [here](Design-Process.md). A shorter overview is below.

## Discussions

Debate pertaining to language features takes place in the form of [Discussions](https://github.com/dotnet/csharplang/discussions) in this repo.

If you want to suggest a feature, discuss current design notes or proposals, etc., please [open a new Discussion topic](https://github.com/dotnet/csharplang/discussions/new).

Discussions that are short and stay on topic are much more likely to be read. If you leave comment number fifty, chances are that only a few people will read it. To make discussions easier to navigate and benefit from, please observe a few rules of thumb:

- Discussion should be relevant to C# language design. If they are not, they will be summarily closed.
- Choose a descriptive topic that clearly communicates the scope of discussion.
- Stick to the topic of the discussion. If a comment is tangential, or goes into detail on a subtopic, start a new discussion and link back.
- Is your comment useful for others to read, or can it be adequately expressed with an emoji reaction to an existing comment?

Language proposals which prevent specific syntax from occurring can be achieved with a [Roslyn analyzer](https://docs.microsoft.com/visualstudio/extensibility/getting-started-with-roslyn-analyzers). Proposals that only make existing syntax optionally illegal will be rejected by the language design committee to prevent increased language complexity.

## Proposals

When a member of the C# LDM finds that a proposal merits consideration by the broader team, they can [Champion](https://github.com/dotnet/csharplang/issues?q=is%3Aopen+is%3Aissue+label%3A%22Proposal+champion%22) it, which means that they will bring it to the C# Language Design Meeting. Proposals are always discussed in linked discussions, not in the champion issue. We didn't always follow this policy, so many champion issues will have discussion on them; we now lock issues to prevent new discussion from occurring on them. Each champion issue will have a discussion link on it.

## Design Process

[Proposals](proposals) evolve as a result of decisions in [Language Design Meetings](meetings), which are informed by [discussions](https://github.com/dotnet/csharplang/discussions), experiments, and offline design work.

In many cases it will be necessary to implement and share a prototype of a feature in order to land on the right design, and ultimately decide whether to adopt the feature. Prototypes help discover both implementation and usability issues of a feature. A prototype should be implemented in a fork of the [Roslyn repo](https://github.com/dotnet/roslyn) and meet the following bar:

- Parsing (if applicable) should be resilient to experimentation: typing should not cause crashes.
- Include minimal tests demonstrating the feature at work end-to-end.
- Include minimal IDE support (keyword coloring, formatting, completion).

Once approved, a feature should be fully implemented in [Roslyn](https://github.com/dotnet/roslyn), and fully specified in the [language specification](spec), whereupon the proposal is moved into the appropriate folder for a completed feature, e.g. [C# 7.1 proposals](proposals/csharp-7.1).

**DISCLAIMER**: An active proposal is under active consideration for inclusion into a future version of the C# programming language but is not in any way guaranteed to ultimately be included in the next or any version of the language. A proposal may be postponed or rejected at any time during any phase of the above process based on feedback from the design team, community, code reviewers, or testing.

### Milestones

We have a few different milestones for issues on the repo:
* [Working Set](https://github.com/dotnet/csharplang/milestone/19) is the set of championed proposals that are currently being actively worked on. Not everything in this milestone will make the next version of C#, but it will get design time during the upcoming release.
* [Backlog](https://github.com/dotnet/csharplang/milestone/10) is the set of championed proposals that have been triaged, but are not being actively worked on. While discussion and ideas from the community are welcomed on these proposals, the cost of the design work and implementation review on these features are too high for us to consider community implementation until we are ready for it.
* [Any Time](https://github.com/dotnet/csharplang/milestone/14) is the set of championed proposals that have been triaged, but are not being actively worked on and are open to community implementation. Issues in this can be in one of 2 states: needs approved specification, and needs implementation. Those that need a specification still need to be presented during LDM for approval of the spec, but we are willing to take the time to do so at our earliest convenience.
* [Likely Never](https://github.com/dotnet/csharplang/milestone/13) is the set of proposals that the LDM has rejected from the language. Without strong need or community feedback, these proposals will not be considered in the future.
* Numbered milestones are the set of features that have been implemented for that particular language version. For closed milestones, these are the set of things that shipped with that release. For open milestones, features can be potentially pulled later if we discover compatibility or other issues as we near release.

## Language Design Meetings

Language Design Meetings (LDMs) are held by the LDT and occasional invited guests, and are documented in Design Meeting Notes in the [meetings](meetings) folder, organized in folders by year. The lifetime of a design meeting note is described in [meetings/README.md](meetings/README.md). LDMs are where decisions about future C# versions are made, including which proposals to work on, how to evolve the proposals, and whether and when to adopt them.

## Language Specification

The current ECMA-334 specification can be found in markdown form on the [C# Language Standard](https://github.com/dotnet/csharpstandard/) repository.

## Implementation

The reference implementation of the C# language can be found in the [Roslyn repository](https://github.com/dotnet/roslyn). This repository also tracks the [implementation status for language features](https://github.com/dotnet/roslyn/blob/main/docs/Language%20Feature%20Status.md). Until recently, that was also where language design artifacts were tracked. Please allow a little time as we move over active proposals.


================================================
FILE: meetings/2013/LDM-2013-10-07.md
================================================
# C# Language Design Notes for Oct 7, 2013

## Agenda
We looked at a couple of feature ideas that either came up recently or deserved a second hearing.
1.	Invariant meaning of names <_scrap the rule_>
2.	Type testing expression <_can’t decide on good syntax_>
3.	Local functions <_not enough scenarios_>
4.	nameof operator <_yes_>

## Invariant meaning of names
C# has a somewhat unique and obscure rule called “invariant meaning in blocks” (documented in section 7.6.2.1 of the language specification) which stipulates that if a simple name is used to mean one thing, then nowhere in the immediately enclosing block can the same simple name be used to mean something else.

The idea is to reduce confusion, make cut & paste refactoring a little more safe, and so on.

It is really hard to get data on who has been saved from a mistake by this rule. On the other hand, everyone on the design team has experience being limited by it in scenarios that seemed perfectly legit.

The rule has proven to be surprisingly expensive to implement and uphold incrementally in Roslyn. This has to do with the fact that it cannot be tied to a declaration site: it is a rule about use sites only, and information must therefore be tracked per use – only to establish in the 99.9% case that no, the rule wasn’t violated with this keystroke either.

### Conclusion
The invariant meaning rule is well intentioned, but causes significant nuisance for what seems to be very little benefit. It is time to let it go.

## Type testing expressions
With declaration expressions you can now test the type of a value and assign it to a fresh variable under the more specialized type, all in one expression. For reference types and nullable value types:
``` c#
if ((var s = e as string) != null) { … s … } // inline type test
```
For non-nullable value types it is a little more convoluted, but doable:
``` c#
if ((var i = e as int?) != null) { … i.Value … } // inline type test
```
One can imagine a slightly nicer syntax using a `TryConvert` method:
``` c#
if (MyHelpers.TryConvert(e, out string s)) { … s … }
```
The signature of the `TryConvert` method would be something like
``` c#
public static bool TryConvert<TSource, TResult>(TSource src, out TResult res);
```
The problem is that you cannot actually implement `TryConvert` efficiently: It needs different logic depending on whether `TResult` is a non-nullable value type or a nullable type. But you cannot overload a method on constraints alone, so you need two methods with different names (or in different classes).

This leads to the idea of having dedicated syntax for type testing: a syntax that will a) take an expression, a target type and a fresh variable name, b) return a boolean for whether the test succeeds, c) introduce a fresh variable of the target type, and d) assign the converted value to the fresh variable if possible, or the default value otherwise.

What should that syntax be? A previous proposal was an augmented version of the “is” operator, allowing an optional variable name to be tagged onto the type:
``` c#
if (e is string s) { … s … } // augmented is operator
```
Opinions on this syntax differ rather wildly. While we agree that some mix of “is” and “as” keywords is probably the way to go, no proposal seems appealing to everyone involved. Here are a few:
``` c#
e is T x
T x is e
T e as x
```
(A few sillier proposals were made:
``` c#
e x is T
T e x as
```
But this doesn’t feel like the right time to put Easter eggs in the language.)

### Conclusion
Probably 90% of cases are with reference (or nullable) types, where the declaration-expression approach is not too horrible. As long as we cannot agree on a killer syntax, we are fine with not doing anything.

## Local functions
When we looked at local functions on Apr 15, we lumped them together with local class declarations, and dismissed them as a package. We may have given them somewhat short shrift, and as we have had more calls for them we want to make sure we do the right thing with local functions in their own right.

A certain class of scenarios is where you need to declare a helper function for a function body, but no other function needs it. Why would you need to declare a helper function? Here are a few scenarios:

* Task-returning functions may be fast-path optimized and not implemented as async functions: instead they delegate to an async function only when they cannot take the fast path.
* Iterators cannot do eager argument validation so they are almost always wrapped in a non-iterator function which does validation and delegates to a private iterator.
* Exception filters can only contain expressions – if they need to execute statements, they need to do it in a helper function.

Allowing these helper functions to be declared inside the enclosing method instead of as private siblings would not only avoid pollution of the class’ namespace, but would also allow them to capture type parameters, parameters and locals from the enclosing method. Instead of writing
``` c#
public static IEnumerable<T> Filter<T>(IEnumerable<T> s, Func<T, bool> p)
{
    if (s == null) throw new ArgumentNullException("s");
    if (p == null) throw new ArgumentNullException("p");
    return FilterImpl<T>(s, p);
}
private static IEnumerable<T> FilterImpl<T>(IEnumerable<T> s, Func<T, bool> p)
{
    foreach (var e in s)
        if (p(e)) yield return e;
}
```
You could just write this:
``` c#
public static IEnumerable<T> Filter<T>(IEnumerable<T> s, Func<T, bool> p)
{
    if (s == null) throw new ArgumentNullException("s");
    if (p == null) throw new ArgumentNullException("p");
    IEnumerable<T> Impl() // Doesn’t need unique name, type params or params
    {
        foreach (var e in s)          // s is in scope
            if (p(e)) yield return e; // p is in scope
    }
    return Impl<T>(s, p);
}
```
The underlying mechanism would be exactly the same as for lambdas: we would generate a display class with a method on it. The only difference is that we would not take a delegate to that method.

While it is nicer, though, it is reasonable to ask if it has that much over private sibling methods. Also, those scenarios probably aren’t super common.

### Inferred types for lambdas
This did bring up the discussion about possibly inferring a type for lambda expressions. One of the reasons they are so unfit for use as local functions is that you have to write out their delegate type. This is particularly annoying if you want to immediately invoke the function:
``` c#
((Func<int,int>)(x => x*x))(3); // What??!?
```
VB infers a type for lambdas, but a fresh one every time. This is ok only because VB also has more lax conversion rules between delegate types, and the result, if you are not careful, is a chain of costly delegate allocations.

One option would be to infer a type for lambdas only when there happens to be a suitable `Func<…>` or `Action<…>` type in scope. This would tie the compiler to the pattern used by the BCL, but not to the BCL itself. It would allow the BCL to add more (longer) overloads in the future, and it would allow others to add different overloads, e.g. with ref and out parameters.

### Conclusion
At the end of the day we are not ready to add anything here. No local functions and no type inference for lambdas.

## The nameof operator
The `nameof` operator is another feature that was summarily dismissed as a tag-along to a bigger, more unwieldy feature: the legendary `infoof` operator.
``` c#
PropertyInfo info = infoof(Point.X);
string name = nameof(Point.X); // "X"
```
While the `infoof` operator returns reflection information for a given language element, `nameof` just returns its name as a string. While this seems quite similar at the surface, there is actually quite a big difference when you think about it more deeply. So let’s do that!

First of all, let’s just observe that when people ask for the `infoof` operator, they are often really just looking to get the name. Common scenarios include throwing `ArgumentException`s and `ArgumentNullException`s (where the parameter name must be supplied to the exception’s constructor), as well as firing `Notify` events when properties change, through the `INotifyPropertyChanged` interface.

The reason people don’t want to just put strings in their source code is that it is not refactoring safe. If you change the name, VS will help you update all the references – but it will not know to update the string literal. If the string is instead provided by the compiler or the reflection layer, then it will change automatically when it’s supposed to.

At a time when we are trying to minimize the use of reflection, it seems wrong to add a feature, `infoof`, that would contribute significantly to that use. `nameof` would not suffer from that problem, as the compiler would just replace it with a string in the generated IL.  It is purely a design time feature.

There are deeper problems with `infoof`, pertaining to how the language element in question is uniquely identified. Let’s say you want to get the `MethodInfo` for an overload of a method `M`. How do you designate which overload you are talking about?
``` c#
void M(int x);
void M(string s);
var info = infoof(M…); // Which M? How do you say it?
```
We’d need to create a whole new language for talking about specific overloads, not to mention members that don’t have names, such as user defined operators and conversions, etc.

Again, though, `nameof` does not seem to have that problem. It is only for named entities (why else would you want the name), and it only gives you the name, so you don’t need to choose between overloads, which all have the same name!

All in all, therefore, it seems that the concerns we have about `infoof` do not apply to `nameof`, whereas much (most?) of its value is retained. How exactly would a `nameof` operator work?

### Syntax
We would want the operator to be syntactically analogous to the existing `typeof(…)`. This means we would allow you to say `nameof(something)` in a way that at least sometimes would parse as an invocation of a method called `nameof`. This is ambiguous with existing code only to the extent that such a call binds. We would therefore take a page out of `var`’s book and give priority to the unlikely case that this binds as a method call, and fall back to `nameof` operator semantics otherwise. It would probably be ok for the IDE to always highlight `nameof` as a keyword.

The operand to `nameof` has to be “something that has a name”. In the spirit of the `typeof` operator we will limit it to a static path through names of namespaces, types and members. Type arguments would never need to be provided, but in every name but the last you may need to provide “generic dimension specifiers” of the shape `<,,,>` to disambiguate generic types overloaded on arity.

The grammar would be something like the following:
> _nameof-expression:_
> * `nameof`   `(`   _identifier_   `)`
> * `nameof`   `(`   _identifier_   `::`   _identifier_   `)`
> * `nameof`   `(`   _unbound-type-name_   `.`   _identifier_   `)`

Where _unbound-type-name_ is taken from the definition of `typeof`. Note that it always ends with an identifier. Even if that identifier designates a generic type, the type parameters (or dimension specifiers) are not and cannot be given. 

### Semantics
It is an error to specify an operand to `nameof(…)` that doesn’t “mean” anything. It can designate a namespace, a type, a member, a parameter or a local, as long as it is something that is in fact declared.

The result of the `nameof` expression would always be a string containing the final identifier of the operand. There are probably scenarios where it would be desirable to have a “fully qualified name”, but that would have to be constructed from the parts. After all, what would be the syntax used for that? C# syntax? What about VB consumers, or doc comments, or comparisons with strings provided by reflection? Better to leave those decisions outside of the language.

### Conclusion
We like the `nameof` operator and see very few problems with it. It seems easy to spec and implement, and it would address a long-standing customer request. With a bit of luck, we would never (or at least rarely) hear requests for `infoof` again.

While not the highest priority feature, we would certainly like to do this.





================================================
FILE: meetings/2013/LDM-2013-10-21.md
================================================
# C# Design Notes for Oct 21, 2013
## Agenda
Primary constructors is the first C# 6.0 feature to be spec’ed and implemented. Aleksey, who is doing the implementing joined us to help settle a number of details that came up during this process. We also did a rethink around Lightweight Dynamic.
1.	Primary Constructors \<fleshed out a few more details>
2.	Lightweight Dynamic \<we examined a much simpler approach>

## Primary Constructors

Primary constructors were first discussed in the design meeting on Apr 15, where we decided to include them, but have been around as a suggestion for much longer. It has great synergy with features such as initializers on auto-properties (May 20), because it puts constructor parameters in scope for initializers.

The evolving “speclet” for primary constructors can be found in the “Csharp 6.0 Speclets” working document in the design notes archive (see link above). It reflects a number of implementation choices, and also (at the time of the meeting) left some issues open, which we settled as best we could. Some decisions may change as we get experience with the feature – indeed the early focus on implementing this feature is so that we can incorporate feedback from usage.

### Partial types

Primary constructors involve a parameter list on “the” class or struct header, as well as an optional argument list on “the” base class specification. But what if the type declaration is split over multiple partial types?

There is different precedence with partial classes. Sometimes elements can occur in only one part (members), sometimes they must occur and be the “same” in all parts (type parameters), sometimes they are optional but must agree where present (accessibility and constraints) and sometimes they are cumulative over parts (attributes).

There seems to be little value in allowing class parameters for primary constructors to occur in multiple parts – indeed it would require us to come up with a notion of sameness that only adds complication to the language. So class parameters are allowed only on one of the parts. Arguments to the base class are allowed only in the part where the class parameters occur. The class parameters are in scope in all the parts. This is also the approach that most resembles what is the case today: constructor parameters occur only in one place, and the privates used to hold their values are in scope in all the parts.

### User-provided constructor body

As currently specified, primary constructors give rise to a constructor that is entirely compiler-generated. There is no syntax for the developer to specify statements to be executed as part of the primary constructor invocation. This is less of an issue than it might seem, since more than 90% of what people do in constructor bodies is probably what primary constructors now do for them – copying parameter values into private fields. Even initialization of other fields can now usually take place in initializers, because the constructor parameters are in scope for those.

Even so, for the remaining scenarios the user would fall off a cliff: they would have to renounce primary constructors and turn them back into explicit constructors. This is a shame, and it is definitely worth considering what syntax we would use to fix this.

A radical idea is to just allow statements directly in the class body. This would be weird for several reasons though. Aside from syntactic issues, there’s the problem of evaluation order relative to fields with initializers: initializers run before the base call, whereas statements in a constructor body usually run after, so interspersing them would have very surprising results.
In reality we’d need to place the statements in a block, and the only question is how we “dress up” the block – if at all. Some ideas:
``` c#
class C(int x): B(x)
{
    // Repeat the full signature – redundant and error prone
    C(int x) { Register(this); } 
    // Class name and empty parens – clashes with noarg constructor syntax, 
    // but similar to static constructors
    C() { Register(this); }
    // Just the class name – a little unfamiliar
    C { Register(this); }
    // Prefix with ‘this’ keyword – again a bit unfamiliar
    this { Register(this); }
    // Just the block – succinct but mysterious – and has the eval order issue
    { Register(this); }
}
```

Many of these options are reasonable. We’ll hold off though and see how the feature fares without user specified statements for now.

### Struct issues

Structs always have a default constructor. Should we allow explicit constructors in a struct with a primary constructor to delegate to the default constructor instead of the primary constructor? I.e. is the following ok?
``` c#
struct S(int x)
{
    public S(bool b) : this() { … }
}
```
It seems that the restriction on explicit constructors to always chain to the primary constructor cannot be upheld just by requiring a this(…) initializer on them: we must also require that it isn’t referencing the default (no-arg) constructor.

Also, members in structs are allowed to assign to ‘this’. Should we allow that also in constructor bodies when there are primary constructors? We probably cannot reasonably prevent it, and people who do this are already in the ‘advanced’ category. But we have to spec that it causes the primary constructor parameters to be reset to their default value.

### Attribute targets

Currently, we allow “method” targets on constructors. We should allow an attribute on a class or a struct with a primary constructor to specify a “method” target in order to be applied to the underlying generated constructor.

We should also allow attributes on the individual parameters of the primary constructor to specify a “field” target in order to be applied to the underlying field. In practice there may be optimizations so that the field is not generated when not needed, but the field target should force the field to be generated.

### Accessibility on primary constructor parameters

There is an idea known from other languages (e.g. Scala, TypeScript) of allowing accessibility modifiers on class parameters. This would mean that a property is generated on the class with the name of the parameter, and the accessibility specified.

This would make some scenarios even more succinct, but it is not a straightforward feature. For instance, parameter names are typically lower case and property names typically upper case. We think this is a feature that can be added later if we feel there is significant further gain. Right now we are willing to bet on the combination of primary constructors and more terse property specification (e.g. with expression bodied properties and initializers for auto-properties) as a sufficiently great advance in the specification of data-like classes and structs.

### Conclusion

We continue to bake the details of primary constructors.

## Lightweight Dynamic

We took a fresh look at Lightweight Dynamic, based on feedback from Dino, who used to work on the “old” dynamic infrastructure.

The purpose of Lightweight Dynamic is to allow the behaviors of operations on an object to be specified programmatically, as part of the implementation of the object’s class. Dino pointed out that most behaviors can already be specified, using operator overloading, user defined conversions and indexers. Really, the “only” things missing are invocation and dotting. So instead of coming up with yet another new infrastructure for programmatic definition of object behaviors, we should just augment the one we’ve had all along with facilities for invocation and member access.

Doing more with less is a pretty attractive idea! So we experimented with what that would look like.

### Invokers

It seems reasonable to allow specification of what it means to invoke an object. The scenario seems similar to indexers, which are a special kind of instance members that can be abstract and virtual, take arguments, and be overloaded on signature.

The main difference would be that parameters are specified in round parentheses, and that the body is simply a method body, rather than a pair of accessors:

``` c#
public int this(int x) { return x*x; } // allow instances to be invoked with ints
```

One could imagine using this feature to build alternatives to delegate types, but more interestingly, this could provide semi-typed invocation capabilities for e.g. service calls:

``` c#
public object this(params object[] args) { … } // generalized dynamic invoker
```

While it is straightforward to imagine this feature, it is also of relatively limited value: You can always provide an explicit Invoke method that the user can call at little extra cost.

``` c#
myOperation.Invoke(5, "Hello"); // instead of
myOperation(5, "Hello");
```

Even so, it is interesting to consider.

### Member access

For programmatic member access it seems superficially attractive – or at least powerful – to allow overriding of the dot operator. Maybe in the form of some kind of operator overload?

``` c#
public static JsonObject operator .(JsonObject receiver, string name) { … }
```

The problem of course is that dot is such a fundamental operator. If you overload it to hide the native meaning, you can hardly do anything with the underlying object. How would you even implement the dot operator without using the built in dot for accessing state etc. on the object?

You could of course have rules like we do for events, where the meaning is different on the inside and the outside. But that is not exactly elegant. The fact of the matter is that overriding dot on a statically typed class is simply too disruptive.

Here is where Visual Basic may provide some interesting inspiration. The typical way you’d implement the dot operator would be some sort of dictionary lookup, and in fact you’d probably be fine if dotting did the same as indexing with a string, only with slightly more elegant syntax. Well, VB has an operator for that: The lookup operator, `!`.

We could essentially resign ourselves to not using dot for “lightweight dynamic” member access, instead using `!` as a just-as-short substitute. We would then simply define these two expressions to mean the same:

``` c#
obj!x
obj["x"]
```

If you want to implement dynamic behavior for member access, you just provide an indexer over strings. Your callers will have to use a `!` instead of a `.`, but that is probably a good thing: that way they can still access your “real” members using a normal dot. This was a real issue with the Lightweight dynamic model we’ve explored before, one that we had yet to find a good solution to.

### Conclusion

We still need to dig deeper here, but we think that adding the `!` lookup operator as a short hand for indexing with a string may quite possibly be the only work we have to do in the language for lightweight dynamic! That is quite possibly the biggest reduction of work associated with a feature we’ve ever accomplished in a single sitting!


================================================
FILE: meetings/2013/LDM-2013-11-04.md
================================================
# C# Design Notes for Nov 4, 2013
## Agenda
Next up for implementation are the features for auto-properties and function bodies, both of which go especially well with primary constructors. For the purpose of spec’ing those, we nailed down a few remaining details. We also took another round discussing member access in the lightweight dynamic scenario.
1. Initialized and getter-only auto-properties \<details decided>
2. Expression-bodied function members \<details decided>
3. Lightweight dynamic \<member access model and syntax discussed>

## Initialized and getter-only auto-properties
We are allowing initializers for auto-properties, and we are allowing getter-only auto-properties, where the underlying field is untouched after the initializer has run. This was last discussed on May 20, and allows declarations like this:
``` c#
public bool IsActive { get; } = true;
```
In order to spec these feature additions there are a couple of questions to iron out.
## Getter-only auto-properties without initializers
Initializers will be optional on get-set auto-properties. Should we allow them to be left out on getter-only properties?
``` c#
public bool IsActive { get; } // No way to get a non-default value in there
```
There’s a symmetry and simplicity argument that we should allow this. However, anyone writing it is probably making a mistake, and even if they really meant it, they (and whoever inherits their code) are probably better off explicitly initializing to the default value.
### Conclusion
We’ll disallow this.
### Is the backing field of getter-only auto-properties read-only?
There’s an argument for fewer differences with get-set auto-properties. However, the field is really never going to change, and any tool that works on the underlying field (e.g. at the IL level) would benefit from seeing that it is indeed readonly. 

Readonly does not prevent setting through reflection, so deserialization wouldn’t be affected.
### Conclusion
Let’s make them readonly. There’s a discrepancy with VB’s decision here, which should be rationalized.
## Expression-bodied function members

This feature would allow the body of methods and of getter-only properties to be expressed very concisely with a single expression. This feature was last discussed on April 15, and would allow code like this:
``` c#
public class Point(int x, int y) {
    public int X => x;
    public int Y => y;
    public double Dist => Math.Sqrt(x * x + y * y);
    public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
}
```
Again, there are a few details to iron out.
### Are we happy with the syntax for expression-bodied properties?
The syntax is so terse that it may not be obvious to the reader that it is a property at all. It is just one character off from a field with an initializer, and lacks the telltale get and/or set keywords. 

One could imagine a slightly more verbose syntax:
``` c#
public int X { get => x; }
```
This doesn’t read quite as well, and gives less of an advantage in terms of terseness.
### Conclusion
We’ll stick with the terse syntax, but be open to feedback if people get confused.
## Which members can have expression bodies?
While methods and properties are clearly the most common uses, we can imagine allowing expression bodies on other kinds of function members. For each kind, here are our thoughts.
### Operators: Yes
Operators are like static methods. Since their implementations are frequently short and always have a result, it makes perfect sense to allow them to have expression bodies:
``` c#
public static Complex operator +(Complex a, Complex b) => a.Add(b);
```
### User defined conversions: Yes
Conversions are just a form of operators:
``` c#
public static implicit operator string(Name n) => n.First + " " + n.Last;
```
### Indexers: Yes
Indexers are like properties, except with parameters:
``` c#
public Customer this[Id id] => store.LookupCustomer(id);
```
### Constructors: No
Constructors have syntactic elements in the header in the form of this(…) or base(…) initializers which would look strange just before a fat arrow. More importantly, constructors are almost always side-effecting statements, and don’t return a value.
### Events: No
Events have add and remove accessors. Both must be specified, and both would be side-effecting, not value returning. Not a good fit.
### Finalizers: No
Finalizers are side effecting, not value returning.
### Conclusion
To summarize, expression bodies are allowed on methods and user defined operators (including conversions), where they express the value returned from the function, and on properties and indexers where they express the value returned from the getter, and imply the absence of a setter.
### void-returning methods
Methods returning void, and async methods returning task, do not have a value-producing return statement. In that respect they are like some of the member kinds we rejected above. Should we allow them all the same?
### Conclusion
We will allow these methods to have expression bodies. The rule is similar to expression-bodied lambdas: the body has to be a statement expression; i.e. one that is “certified” to be executed for the side effect.
## Lightweight dynamic member access
At the design meeting on Oct 21, we discussed options for implementing “user-defined” member access. There are two main directions:
- Allow users to override the meaning of dot
- Introduce a “dot-like” syntax for invoking string indexers

The former really has too many problems, the main one being what to do with “real” dot. Either we make “.” retain is current meaning and only delegate to the user-supplied meaning when that fails. But that means the new dot does not get a full domain of names. Or we introduce an escape hatch syntax for “real dot”. But then people would start using that defensively everywhere, especially in generated code. It also violates substitutability where o.x suddenly means something else on a subtype than a supertype. 

We strongly prefer the latter option, providing a “dot-like” syntax that translates into simply invoking a string indexer with the provided identifier as a string. This has the added benefit of working with existing types that have string indexers. The big question of course is what dot-like syntax. Here are some candidates we looked at in order to home in on a design philosophy:
``` c#
x!Foo   // Has a dot, but not as a separate character
x."Foo" // That looks terrible, too much like any value could be supplied
x.[Foo] // Doesn’t feel like Foo is a member name
x.#Foo  // Not bad
x.+Foo  // Hmmmm
```
Some principles emerge from this exercise:
- Using "…" or […] kills the illusion of it being a member name
- Having characters after the identifier breaks the flow
- Using a real dot feels right, and would help with the tooling experience
- What comes after that real dot really matters!

### Conclusion
We like the “dot-like” syntax approach to LW dynamic member access, and we think it should be of the form x.\<glyph>Foo for some value of \<glyph>.


================================================
FILE: meetings/2013/LDM-2013-12-16.md
================================================
# C# Design Notes for Dec 16, 2013

## Agenda
This being the last design meeting of the year, we focused on firming up some of the features that we’d like to see prototyped first, so that developers can get going on implementing them.
1. Declaration expressions <_reaffirmed scope rules, clarified variable introduction_>
2. Semicolon operator <_reaffirmed enclosing parentheses_>
3. Lightweight dynamic member access <_decided on a syntax_>

## Declaration expressions
On Sep 23 we tentatively decided on rules for what the scope is when a variable is introduced by a declaration expression. Roughly speaking, the rules put scope boundaries around “structured statements”. While this mostly makes sense, there is one idiom, the “guard clause” pattern, that falls a little short here:
``` c#
if (!int.TryParse(s, out int i)) return false; // or throw, etc.
… // code ideally consuming i
```
Since the variable `i` would be scoped to the if statement, using a declaration statement to introduce it inside of the if would not work.

We talked again about whether to rethink the scope rules. Should we have a different rule to the effect essentially of the variable declaration being introduced “on the preceding statement”? I.e. the above would be equivalent to
``` c#
int i;
if (!int.TryParse(s, out i)) return false; // or throw, etc.
… // code consuming i
```
This opens its own can of worms. Not every statement _has_ a preceding statement (e.g. when being nested in another statement). Should it bubble up to the enclosing statement recursively? Should it introduce a block around the current statement to hold the generated preceding statement, etc.

More damning to this idea is the issue of initialization. If a variable with an initializer introduced in e.g. a while loop body is understood to really be a single variable declared outside of the loop, then that same variable would be re-initialized every time around the loop. That seems quite counterintuitive.

This brings us to the related issue about variable lifetimes. When a variable is introduced somewhere in a loop, is it a fresh variable each time around? It would probably seem strange if it weren’t. In fact we took a slight breaking change in C# 5.0 in order to make that the case for the loop variable in `foreach`, because the alternative didn’t make sense to people, and tripped them up when they were capturing the variable in lambdas, etc.

### Conclusion
We keep the scope rules described earlier, despite the fact that the guard clause example doesn’t work. We’ll look at feedback on the implementation and see if we need to adjust. On variable lifetimes, each iteration of a loop will introduce its own instance of a variable introduced in the scope of that loop. The only exception is if it occurs in the initializer of a for loop, because that part is evaluated only on entry to the loop. 

## Semicolon operator
We previously decided that a sequence of expressions separated by semicolons need to be enclosed in parentheses. This is so that we don’t get into situations where e.g. commas and semicolons are interspersed among expressions and it isn’t visually clear what the precedence is.

We discussed briefly whether those parentheses are necessary even when there is other bracketing around the semicolon-separated expressions.

### Conclusion
It’s not worth having special rules for this. Instead, semicolons are a relatively straightforward addition to parenthesized expressions – something like this:

> _parenthesized-expression:_
> *  `(`   *expression-sequence*\_opt   expression_   `)`

> _expression-sequence:_
> *    *expression-sequence*\_opt   _statement-expression_   `;`
> *    *expression-sequence*\_opt   _declaration-expression_   `;`

## Lightweight dynamic member access
On Nov 4 we decided that lightweight member access should take the form `x.<glyph>Foo` for some value of `<glyph>`. One candidate for the glyph is `#`, so that member access would look like this:
``` c#
payload.#People[i].#Name
```
However, `#` plays really badly with preprocessor directives. It seems almost impossible to come up with syntactic rules that reconcile with the deep lexer-based recognition of `#`-based preprocessor directives. After searching the keyboard for a while, we settled on ‘`$`’ as a good candidate. It sort of invokes a “string” aspect in a tip of the hat to classic Basic:
``` c#
payload.$People[i].$Name
```
One key aspect of dynamicness that we haven’t captured so far is the ability to declaratively construct an object with “lightweight dynamic members”, i.e. with entries accessible with string keys. A core syntactic insight here is to think of `$Foo` above as a unit – as a “lightweight dynamic member name”. What this enables is to think of object construction in terms of object initializers – where the member names are dynamic:
``` c#
var json = new JsonObject 
{ 
    $foo = 1,
    $bar = new JsonArray { "Hello", "World" },
    $baz = new JsonObject { $x = 1, $y = 2 }
};
```
We could also consider allowing a free standing `$Foo` in analogy with a free standing simple name being able to reference an enclosing member in the implicit meaning of `this.$Foo`. This seems a little over the top, so we won’t do that for now.
One thing to consider is that objects will sometimes have keys that aren’t identifiers. This is quite common in Json payloads. That’s fine as far as member access is concerned: just fall back to indexing syntax when necessary:
``` c#
payload.$People[i].["first name"]
```
It would be nice to also be able to initialize such “members” in object initializers. This leads to the idea of a generalized “dictionary initializer” syntax in object initializers:
``` c#
var payload = new JsonObject
{
    ["first name"] = "Donald",
    ["last name"] = "Duck",
    $city = "Duckburg" // equivalent to ["city"] = "Duckburg"
};
```
So just as `x.$Foo` is a shorthand for `x["Foo"]` in expressions, `$Foo=value` is shorthand for `["Foo"]=value` in object initializers. That syntax in turn is a generalized dictionary initializer syntax, that lets you index and assign on the newly created object, so that the above is equivalent to
``` c#
var __tmp = new JsonObject();
__tmp["first name"] = "Donald";
__tmp["last name"] = "Duck";
__tmp["city"] = "Duckburg";
var payload = __tmp;
```
It could be used equally well with non-string indexers.
A remaining nuisance is having to write all the type names during construction. Could some of them be inferred, or a default be chosen? That’s a topic for a later time.

### Conclusion
We’ll introduce a notion of dictionary initializers `[index]=value`, which are indices enclosed in `[…]` being assigned to in object initializers. We’ll also introduce a shorthand `x.$Foo` for indexing with strings `x["Foo"]`, and a shorthand `$Foo=value` for a string dictionary initializer `["Foo"]=value`.


================================================
FILE: meetings/2013/README.md
================================================
# C# Language Design Notes for 2013

Overview of meetings and agendas for 2013

## Oct 7, 2013

[C# Language Design Notes for Oct 7, 2013](LDM-2013-10-07.md)

1.	Invariant meaning of names <*scrap the rule*>
2.	Type testing expression <*can’t decide on good syntax*>
3.	Local functions <*not enough scenarios*>
4.	nameof operator <*yes*>

[C# Language Design Notes for Oct 21, 2013](LDM-2013-10-21.md)

1.	Primary Constructors <*fleshed out a few more details*>
2.	Lightweight Dynamic <*we examined a much simpler approach*>

## Nov 4, 2013

[C# Language Design Notes for Nov 4, 2013](LDM-2013-11-04.md)

1. Initialized and getter-only auto-properties <*details decided*>
2. Expression-bodied function members <*details decided*>
3. Lightweight dynamic <*member access model and syntax discussed*>

## Dec 16, 2013

[C# Language Design Notes for Dec 16, 2013](LDM-2013-12-16.md)

1. Declaration expressions <*reaffirmed scope rules, clarified variable introduction*>
2. Semicolon operator <*reaffirmed enclosing parentheses*>
3. Lightweight dynamic member access <*decided on a syntax*>


================================================
FILE: meetings/2014/LDM-2014-01-06.md
================================================
# C# Design Notes for Jan 6, 2014

Notes are archived [here](https://roslyn.codeplex.com/wikipage?title=CSharp%20Language%20Design%20Notes).

## Agenda
In this meeting we reiterated on the designs of a couple of features based on issues found during implementation or through feedback from MVPs and others.
1.	Syntactic ambiguities with declaration expressions <_a solution adopted_>
2.	Scopes for declaration expressions <_more refinement added to rules_>

# Syntactic ambiguities with declaration expressions
There are a couple of places where declaration expressions are grammatically ambiguous with existing expressions. The knee-jerk reaction would be to prefer the existing expressions for compatibility, but those turn out to nearly always lead to semantic errors later.

There are two kinds of full ambiguities (i.e. ones that don’t resolve with more lookahead):
``` c#
a * b // multiplication expression or uninitialized declaration of pointer?
a < b > c // nested comparison or uninitialized declaration of generic type?
```
The latter one exists also in a method argument version that seems more realistic:
``` c#
a ( b < c , d > e ) // two arguments or one declaration expression?
```
However, in all these cases the expression, when interpreted as a declaration expression, is uninitialized. This means that in the vast majority of cases (except for structs with no accessible members) it will be considered unassigned. Which means that it will be a semantic error for it to occur as a value: it has to occur in one of the few places where an unassigned variable is allowed:

1. On the left hand side of an assignment expression
2. As an argument to an out parameter
3. In parentheses in one of the previous positions

Those are places where a multiplication or comparison expression cannot currently occur, because they are always values, never variables. We can therefore essentially split the world neatly for the two interpretations of the ambiguous expressions:

* If they occur in a place where a variable is required, they are parsed as declaration expressions
* Everywhere else, they are parsed as they are today.

This is a purely syntactic distinction. Rules of definite assignment etc. aren’t actually used by the compiler to decide, just by us designers to justify that the rule isn’t breaking.

There is one potential future conflict we can imagine: If we start allowing ref returning methods and those include user defined overloads of operators, then you could imagine someone defining an overload of “`*`” that returns a ref, and would therefore give meaning to the expression `(a*b) = c`, even when interpreted as multiplication. The rules as proposed here would not allow that; they would try to see `(a*b)` as a parenthesized declaration expression of a variable `b` with pointer type `a*`.

### Conclusion
We like the rule that parsing prefers declaration expressions in ambiguous cases _only_ in places where a variable is required: when occurring as an out argument, on the left hand side of an assignment, or nested in any number of parentheses within those. This is non-breaking, and doesn’t seem too harmful to the future design space.

## Scopes for declaration expressions
The initial rules for declaration expression scopes are in need of some refinement in at least two scenarios:
``` c#
if (…) m(int x = 1); else m(x = 2); // cross pollution between branches?
while (…) m(int x = 1; x++); // survival across loop iterations?
```
We want to make sure that declarations are isolated between branches and loop iterations. This means we need to add more levels of scopes. Essentially, whenever an _embedded-expression_ occurs as an embedded expression (as opposed to where any _expression_ can occur), we want to introduce a new nested scope.

Additionally, for for-loops we want to nest scopes for each of the clauses in the header:
``` c#
for (int i = (int a = 0);
     i < (int b = 10); // i and a in scope here
     i += (int c = 1)) // i, a and b in scope here
  (int d += i);        // i, a and b but not c in scope here
```
It’s as if the for loop was rewritten as
``` c#
{
  int i = (int a = 0);
  while (i < (int b = 10))
  {
    { i += (int c = 1)); }
    (int d += i);
  }
}
```

### Conclusion
We’ll adopt these extra scope levels which guard against weird spill-over.


================================================
FILE: meetings/2014/LDM-2014-02-03.md
================================================
# C# Language Design Notes for Feb 3, 2014

## Agenda
We iterated on some of the features currently under implementation 
1.  Capture of primary constructor parameters <_only when explicitly asked for with new syntax_>
1.  Grammar around indexed names <_details settled_>
1.  Null-propagating operator details <_allow indexing, bail with unconstrained generics_>

## Capture of primary constructor parameters
Primary constructors as currently designed and implemented lead to automatic capture of parameters into private, compiler-generated fields of the object whenever those parameters are used after initialization time.

It is becoming increasingly clear that this is quite a dangerous design. To illustrate, what’s wrong with this code?
``` c#
public class Point(int x, int y)
{
    public int X { get; set; } = x;
    public int Y { get; set; } = y;
    public double Dist => Math.Sqrt(x * x + y * y);
    public void Move(int dx, int dy)
    {
        x += dx; y += dy;
    }
}
```
This appears quite benign, but is in fact catastrophically wrong. The use of `x` and `y` in `Dist` and `Move` causes these values to be captured as private fields. The auto-properties `X` and `Y` each cause their own backing fields to be generated, initialized with the `x` and `y` values passed in to the primary constructors. But from then on, `X` and `Y` lead completely distinct lives from `x` and `y`. Assignments to the `X` and `Y` properties will cause them to be observably updated, but the value of `Dist` remains unchanged. Conversely, changes through the `Move` method will reflect in the value of `Dist`, but not affect the value of the properties.

The way for the developer to avoid this is to be extremely disciplined about not referencing `x` and `y` except in initialization code. But that is like giving them a gun already pointing at their foot: sooner or later it will go subtly wrong, and they will have hard to find bugs.

There are other incarnations of this problem, e.g. where the parameter is passed to the base class and captured multiple times.

There are also other problems with implicit capture: we find, especially from MVP feedback, that people quickly want to specify certain things about the generated fields, such as readonly-ness, attributes, etc. We could allow those on the parameters, but they quickly don’t look like parameters anymore.

The best way for us to deal with this is to simply disallow automatic capture. The above code would be disallowed, and given the same declarations of `x`, `y`, `X` and `Y`, `Dist` and `Move` would have to written in terms of the properties:

``` c#
    public double Dist => Math.Sqrt(X * X + Y * Y);
    public void Move(int dx, int dy)
    {
        X += dx; Y += dy;
    }
```

Now this raises a new problem. What if you want to capture a constructor parameter in a private field and have no intention of exposing it publicly. You can do that explicitly:

``` c#
public class Person(string first, string last)
{
    private string _first = first;
    private string _last = last;
    public string Name => _first + " " + _last;
}
```

The problem is that the “good” lower case names in the class-level declaration space are already taken by the parameters, and the privates are left with (what many would consider) less attractive naming options.

We could address this in two ways (that we can think of) in the primary constructor feature: 
1. Allow primary constructor parameters and class members to have the same names, with the excuse that their lifetimes are distinct: the former are only around during initialization, where access to the latter through this is not yet allowed.
1. Introduce a syntax for explicitly capturing a parameter. If you ask for it, presumably you thought through the consequences.

The former option seems mysterious: two potentially quite different entities get to timeshare on the same name? And then you’d get confusing initialization code like this:

``` c#
    private string first = first; // WHAT???
    private string last = last;
```

It seems that the latter option is the better one. We would allow field-like syntax to occur in a parameter list, which is a little odd, but kind of says what it means. Specifically specifying an accessibility on a parameter (typically private) would be what triggers capture as a field:

``` c#
public class Person(private string first, private string last)
{
    public string Name => _first + " " + _last;
}
```

Once there’s an accessibility specified, we would also allow other field modifiers on the parameter; readonly probably being the most common. Attributes could be applied to the field in the same manner as with auto-properties: through a field target.

Conclusion
We like option two. Let’s add syntax for capture and not do it implicitly.

Grammar for indexed names
For the lightweight dynamic features, we’ve been working with a concept of “pseudo-member” or _indexed name_ for the `$identifier` notation.

We will introduce this as a non-terminal in the grammar, so that the concept is reified. However, for the constructs that use it (as well as ordinary identifiers) we will create separate productions, rather than unify indexed names and identifiers under a common grammatical category.

For the stand-alone dictionary initializer notation of `[expression]` we will not introduce a non-terminal.

## Null-propagating operator details
Nailing down the design of the null-propagating operator we need to decide a few things:

### Which operators does it combine with?
The main usage of course is with dot, as in `x?.y` and `x?.m(…)`. It also potentially makes sense for element access `x?[…]` and invocation `x?(…)`. And we also have to consider interaction with indexed names, as in `x?.$y`.

We’ll do element access and indexed member access, but not invocation. The former two make sense in the context that lightweight dynamic is addressing. Invocation seems borderline ambiguous from a syntactic standpoint, and for delegates you can always get to it by explicitly calling Invoke, as in `d?.Invoke(…)`.

### Semantics
The semantics are like applying the ternary operator to a null equality check, a null literal and a non-question-marked application of the operator, except that the expression is evaluated only once:

``` c#
e?.m(…)   =>   ((e == null) ? null : e0.m(…))
e?.x      =>   ((e == null) ? null : e0.x)
e?.$x     =>   ((e == null) ? null : e0.$x)
e?[…]     =>   ((e == null) ? null : e0[…])
```

Where `e0` is the same as `e`, except if `e` is of a nullable value type, in which case `e0` is `e.Value`. 

### Type
The type of the result depends on the type `T` of the right hand side of the underlying operator: 
* If `T` is (known to be) a reference type, the type of the expression is `T`
* If `T` is (known to be) a non-nullable value type, the type of the expression is `T?`
* If `T` is (known to be) a nullable value type, the type of the expression is `T`
* Otherwise (i.e. if it is not known whether `T` is a reference or value type) the expression is a compile time error.



================================================
FILE: meetings/2014/LDM-2014-02-10.md
================================================
# C# Design Notes for Feb 10, 2014

## Agenda
1.	Design of using static <_design adopted_>
2.	Initializers in structs <_allow in certain situations_>
3.	Null-propagation and unconstrained generics <_keep current design_>

## Design of using static
The “using static” feature was added in some form to the Roslyn codebase years ago, and sat there quietly waiting for us to decide whether to add it to the language. Now it’s coming out, it’s time to ensure it has the right design.
### Syntax
Should the feature have different syntax from namespace usings, or should it be just like that, but just specifying a type instead? The downside of keeping the current syntax is that we need to deal with ambiguities between types and namespaces with the same name. That seems relatively rare, though, and sticking with current syntax definitely makes it feel more baked in:
``` c#
using System.Console;
```
as opposed to, e.g.:
``` c#
using static System.Console;
```
#### Conclusion
We’ll stick with the current syntax.

### Ambiguities
This leads to the question of how to handle ambiguities when there are both namespaces and types of a given name. We clearly need to prefer namespaces over types for compatibility reasons. The question is whether we make a choice at the point of the specified name, or whether we allow “overlaying” the type and the namespace, disambiguating at the next level down by preferring names that came from the namespace over ones from the type.

#### Conclusion
We think overlaps are sufficiently rare that we’ll go with the simple rule: A namespace completely shadows a type of the same name, and you can’t import the members of such a type. If this turns out to be a problem we’re free to loosen it up later.

### Which types can you import?
Static classes, all classes, enums? It seems it is almost always a mistake to import non-static types: they will have names that are designed to be used with the type name, such as `Create`, `FromArray`, `Empty`, etc., that are likely to appear meaningless on their own, and clash with others. Enums are more of a gray area. Spilling the enum members to top-level would often be bad, and could very easily lead to massive name clashes, but sometimes it’s just what you want.

#### Conclusion
We’ll disallow both enums and non-static classes for now.

### Nested types
Should nested types be imported as top-level names?

#### Conclusion
Sure, why not? They are often used by the very members that are being “spilled”, so it makes sense that they are spilled also.

### Extension methods
Should extension methods be imported as extension methods? As ordinary static methods? When we first introduced extension methods, a lot of people asked for a more granular way of applying them. This could be it: get the extension methods just from a single class instead of the whole namespace. For instance:
``` c#
using System.Linq.Enumerable;
```
Would import just the query methods for in-memory collections, not those for `IQueryable<T>`.
On the other hand, extension methods are designed to be used as such: you only call them as static methods to disambiguate. So it seems wrong if they are allowed to pollute the top-level namespace as static methods. On the _other_ other hand, this would be the first place in the language where an extension method wouldn’t be treated like a static method.

#### Conclusion
We will import extension methods as extension methods, but not as static methods. This seems to hit the best usability point.

## Initializers in structs
Currently, field initializers aren’t allowed in structs. The reason is that initializers _look_ like they will be executed every time the struct is created, whereas that would not be the case: If the struct wasn’t `new`’ed, or it was `new`’ed with the default constructor, no user defined code would run. People who put initializers on fields might not be aware that they don’t always run, so it’s better to prevent them.

It would be nice to have the benefits of primary constructors on structs, but that only really flies if the struct can make use of the parameters in scope through initializers. Also, we now have initializers for auto-properties, making the issue worse. What to do?

We can never prevent people from having uninitialized structs, and the struct type authors still need to make sure that an uninitialized struct is meaningful. However, if a struct has user-defined constructors, chances are they know what they’re doing and initializers wouldn’t make anything worse. However, initializers would only run if the user-defined constructors don’t chain to the default constructor with `this()`.

### Conclusion
Let’s allow field and property initializers in structs, but only if there is a user-defined constructor (explicit or primary) that does not chain to the default constructor. If people want to initialize with the default constructor first, they should call it from their constructor, rather than chain to it.
``` c#
struct S0 { public int x = 5; } // Bad
struct S1 { public int x = 5; S1(int i) : this() { x += i; } } // Bad
struct S2 { public int x = 5; S2(int i) { this = new S2(); x += i; } } // Good
struct S3(int i) { public int x = 5 + i; } // Good
```
## Unconstrained generics in null-propagating operator
We previously looked at a problem with the null-propagating operator, where if the member accessed is of an unconstrained generic type, we don’t know how to generate the result, and what its type should be:
``` c#
var result = x?.Y;
```
The answer is different when `Y` is instantiated with reference types, non-nullable value types and nullable value types, so there’s nothing reasonable we can do when we don’t know which.
The proposal has been raised to fall back to type `object`, and generate code that boxes (which is a harmless operation for values that are already of reference type).

### Conclusion
This seems like a hack. While usable in some cases, it is weirdly different from the mainline semantics of the feature. Let’s prohibit and revisit if it becomes a problem.



================================================
FILE: meetings/2014/LDM-2014-04-21.md
================================================
# C# Language Design Notes for Apr 21, 2014

## Agenda
In this design meeting we looked at some of the most persistent feedback on the language features showcased in the BUILD CTP, and fixed up many of the most glaring issues.

1.	Indexed members <_lukewarm response, feature withdrawn_>
2.	Initializer scope <_new scope solves all kinds of problems with initialization_>
3.	Primary constructor bodies <_added syntax for a primary constructor body_>
4.	Assignment to getter-only auto-properties from constructors <_added_>
5.	Separate accessibility for type and primary constructor <_not worthy of new syntax_>
6.	Separate doc comments for field parameters and fields <_not worthy of new syntax_>
7.	Left associative vs short circuiting null propagation <_short circuiting_>

## Indexed members
The indexed member feature – `e.$x` and `new C { $x = e }` – has been received less than enthusiastically. People aren’t super happy with the syntax, but most of all they aren’t very excited about the feature.

We came to this feature in a roundabout way, where it started out having much more expressiveness. For instance, it was the way you could declaratively create an object with values at given indices. But given the dictionary initializer syntax – `new C { ["x"] = e }` – the `$` syntax is again just thin sugar for using string literals in indexers. Is that worth new syntax? It seems not.

### Conclusion
We’ll pull the feature. There’s little love for it, and we shouldn’t litter the language unnecessarily. If this causes an outcry, well that’s different feedback, and we can then act on that.

## Initializer scope
There are a couple of things around primary constructors and scopes that are currently annoying:

1.	You frequently want a constructor parameter and a (private) field with the same name. In fact we have a feature just for that – the so-called field parameters, where primary constructors annotated with an accessibility modifier cause a field to be also emitted. However, if you try to declare this manually, we give an error because members and primary constructor parameters are in the same declaration space.

2.	We have special rules for primary constructor parameters, making it illegal to use them after initialization time, even though they are “in scope”.

So in this code:
``` c#
public class ConfigurationException(Configuration configuration, string message) 
    : Exception(message)
{
    private Configuration configuration = configuration;
    public override string ToString() => message + "(" + configuration + ")";
}
```
The declaration of the field `configuration` is currently an error, because it clashes with the parameter of the same name in the same declaration space, but it would be nice if it just worked.

The use of `message` in a method body is and should be an error, but it would be preferable if that was a more natural consequence of existing scoping rules, instead of new specific restrictions.

An idea to fix this is to introduce what we’ll call the ___initialization scope___. This is a scope and declaration space that is nested within the type declaration’s scope and declaration space, and which includes the parameters and base initializer arguments of a primary constructor (if any) and the expressions in all member initializers of the type. 

That immediately means that this line becomes legal and meaningful:

``` c#
    private Configuration configuration = configuration;
```

The _field_ `configuration` no longer clashes with the _parameter_ `configuration`, because they are no longer declared in the same declaration space: the latter’s is nested within the former’s. Moreover the reference to `configuration` in the initializer refers to the parameter, not the field, because while both are in scope, the parameter is nearer.

Some would argue that a line like the above is a little confusing. You are using the same name to mean different things. That is a fair point. The best way to think of it is probably the corresponding line in a normal constructor body:

``` c#
    this.configuration = configuration;
```

Which essentially means the same thing. Just as we’ve gotten used to `this` disambiguating that line, we’ll easily get used to the leading modifier and type of the field declaration disambiguating the field initializer.

The initialization scope also means that this line is naturally disallowed:

``` c#
    public override string ToString() => message + "(" + configuration + ")";
```

Because the reference to `message` does not appear within the initialization scope, and the parameter is therefore not in scope. If there was a field with that name, the field would get picked up instead; it wouldn’t be shadowed by a parameter which would be illegal to reference.

A somewhat strange aspect of the initialization scope is that it is textually discontinuous: it is made up of bits and pieces throughout a type declaration. Hopefully this is not too confusing: conceptually it maps quite clearly to the notion of “initialization time”. Essentially, the scope is made up of “the code that runs when the object is initialized”.

There are some further desirable consequences of introducing the initialization scope:

### Field parameters
The feature of field parameters is currently the only way to get a primary constructor parameter and a field of the same name:

``` c#
public class ConfigurationException(private Configuration configuration, …)
```

With the initialization scope, the feature is no longer special magic, but just thin syntactic sugar over the field declaration above. If for some reason field parameters don’t work for you, you can easily fall back to an explicit field declaration with the same name as the parameter.

It raises the question of whether we’d even _need_ field parameters, but they still seem like a nice shorthand.

### The scope of declaration expressions in initializers
In the current design, each initializer provides its own isolated scope for declaration expressions: there was no other choice really. With the initialization scope, however, declaration expressions in initializers would naturally use that as their scope, allowing the use of locals to flow values between initializers. This may not be common, but you can certainly imagine situations where that comes in handy:

``` c#
public class ConfigurationException(Configuration configuration, string message) 
    : Exception(message)
{
    private Configuration configuration = configuration;
    public bool IsRemote { get; } = (var settings = configuration.Settings)["remote"];
    public bool IsAsync { get; } = settings["async"];
    public override string ToString() => Message + "(" + configuration + ")";
}
```

The declaration expression in `IsRemote`’s initializer captures the result of evaluating `configuration.Settings` into the local variable `settings`, so that it can be reused in the initializer for `IsAsync`.

We need to be a little careful about partial types. Since the “textual order” between different parts of a partial type is not defined, it does not seem reasonable to share variables from declaration expressions between different parts. Instead we should introduce a scope within each part of a type containing the field and property initializers contained in that part. This scope is then nested within the initializer scope, which itself covers all the parts.

A similar issue needs to be addressed around the argument to the base initializer. Textually it occurs _before_ the member initializers, but it is evaluated _after_. To avoid confusion, the argument list needs to be in its own scope, nested inside the scope that contains the field and property initializers (of that part of the type). That way, locals introduced in the argument list will not be in scope in the initializers, and members introduced in the initializers cannot be used in the argument list (because their use would textually precede their declaration).

### Primary constructors in VB
Importantly, the notion of the initialization scope would also make it possible to introduce primary constructors in VB. The main impediment to this has been that, because of case insensitivity, the restriction that primary constructor parameters could not coexist with members of the same name became too harsh. If you need both a parameter, a backing field and a property, you quickly run out of names!

The initialization scope helps with that, by introducing a separate scope that the parameters can live in, so they no longer clash with other names.

Unlike C#, VB today allows initializers to reference previously initialized fields. With the initialization scope this would still be possible, as long as there’s not a primary constructor parameter shadowing that field. And if there is, you probably want the parameter anyway. An if you don’t, you can always get at the field through `Me` (VB’s version of `this`).

It is up to the VB design team whether to actually add primary constructors this time around, but it is certainly nice to have a model that will work in both languages.

### Conclusion
The initialization scope solves many problems, and leaves the language cleaner and with less magic. This clearly outweighs the slight oddities it comes with.

## Primary constructor bodies
By far the most commonly reported reason why people cannot use primary constructors is that they don’t allow for easy argument validation: there is simply no “body” within which to perform checks and throw exceptions.

We could certainly change that. The simplest thing, syntactically, is to just let you write a block directly in the type body, and that block then gets executed when the object is constructed:

``` c#
public class ConfigurationException(Configuration configuration, string message) 
    : Exception(message)
{
    {
        if (configuration == null) 
        {
            throw new ArgumentNullException(nameof(configuration));
        }
    }
    private Configuration configuration = configuration;
    public override string ToString() => Message + "(" + configuration + ")";
}
```

This looks nice, but there is a core question we need to answer: when _exactly_ is that block executed? There seem to be two coherent answers to that, and we need to choose:

1.	The block is an ___initializer body___. It runs before the base call, following the same textual order as the surrounding field and property initializers. You could even imagine allowing multiple of them interspersed with field initialization, and they can occur regardless of whether there is a primary constructor.

2.	The block is a ___constructor body___. It is the body of the primary constructor and therefore runs after the base call. You can only have one, and only if there is a primary constructor that it can be part of.

Both approaches have pros and cons. The initializer body corresponds to a similar feature in Java, and has the advantage that you can weed out bad parameters before you start digging into them or pass them to the base initializer (though arguments passed to the base initializer should probably be validated by the base initializer rather than in the derived class anyway).

As an example of this issue, our previous example where an initializer digs into the contents of a primary constructor parameter, wouldn’t work if the validation was done in a constructor body, after initialization (here in a simplified version):

``` c#
    public bool IsRemote { get; } = configuration.Settings["remote"];
```

If the passed-in `configuration` is null, this would yield a null reference exception before a constructor body would have a chance to complain (by throwing a better exception). Instead, in a constructor body interpretation, the initialization of `IsRemote` would either have to happen in the constructor body as well, following the check, or it would have to make copious use of the null propagating operator that we’re also adding:

``` c#
    public bool IsRemote { get; } = configuration?.Settings?["remote"] ?? false;
```

On the other hand, the notion of a constructor body is certainly more familiar, and it is easy to understand that the block is stitched together with the parameter list and the base initializer to produce the constructor declaration underlying the primary constructor.

Moreover, a constructor body has access to fields and members, while `this` access during initialization time is prohibited. Therefore, a constructor body can call helper methods etc. on the instance under construction; also a common pattern.

### Conclusion
At the end of the day we have to make a choice. Here, familiarity wins. While the initializer body approach has allure, it is also very much a new thing. Constructor bodies on the other hand work the way they work. The downsides have workarounds. So a constructor body it is.

In a partial type, the constructor body must be in the same part as the primary constructor. Scope-wise, the constructor body is nested within the scope for the primary constructor’s base arguments, which in turn is nested within the scope for the field and property initializers of that part, which in turn is nested within the initialization scope that contains the primary constructor parameters:

``` c#
partial class C(int x1) : B(int x3 = x1 /* x2 in scope but can’t be used */)
{
    public int X0 { get; } = (int x2 = x1);
    {
        int x4 = X0 + x1 + x2 + x3;
    }
}
```

Let’s look at the scopes (and corresponding declaration spaces) nested in each other here:

* The scope `S4` spans the primary constructor body. It directly contains the local variable `x4`, and is nested within `S3`.
* The scope `S3` spans `S4` plus the argument list to the primary constructor’s base initializer. It directly contains the local variable `x3`, and is nested within `S2`.
* The scope `S2` spans `S3` plus all field and property initializers in this part of the type declaration. It directly contains the local variable `x2`, and is nested within `S1`.
* The scope `S1` spans `S2` plus similar “`S2`’s” from other parts of the type declaration, plus the parameter list of the primary constructor. It directly contains the parameter `x1`, and is nested within `S0`.
* The scope `S0` spans all parts of the whole type declaration, including `S1`. It directly contains the property `X0`.

On top of this, the usual rule applies for local variables, that they cannot be used in a position that textually precedes their declaration.

## Assignment to getter-only auto-properties
There are situations where you cannot use a primary constructor. We have to make sure that you do not fall off too steep of a cliff when you are forced to abandon primary constructor syntax and use an ordinary constructor.

One of the main nuisances that has been pointed out is that the only way to initialize a getter-only auto-property is with an initializer. If you want to initialize it from constructor parameters, you therefore need to have a primary constructor, so those parameters can be in scope for initialization. If you cannot have a primary constructor, then the property cannot be a getter-only auto-property: You have to fall back to existing, more lengthy and probably less fitting property syntax.

That’s a shame. The best way to level the playing field here is to allow assignment to getter-only auto-properties from within constructors: 
``` c#
public class ConfigurationException : Exception
{
    private Configuration configuration;
    public bool IsRemote { get; }
    public ConfigurationException(Configuration configuration, string message) 
        : base(message)
    {
        if (configuration == null) 
        {
            throw new ArgumentNullException(nameof(configuration));
        }
        this.configuration = configuration;
        IsRemote = configuration.Settings["remote"];
    }
}
```

The assignment to `IsRemote` would go directly to the underlying field (since there is no setter to call). Thus, semantics are a little different from assignment to get/set auto-properties, where the setter is called even if you assign from a constructor. The difference is observable if the property is virtual. We could restore symmetry by changing the meaning of assignment to a get/set auto-property to also go directly to the backing field, but that would be a breaking change.

### Conclusion
Let’s allow assignment to getter-only auto-properties from constructor bodies. It translates into assignment directly to the underlying field (which is `readonly`). We are ok with the slight difference in semantics from get/set auto-property assignment.

## Separate accessibility on type and primary constructor
There are scenarios where you don’t want the constructors of your type to have the same accessibility as the type. A common case is where the type is public, but the constructor is private or protected, object construction being exposed only through factories.

Should we invent syntax so that a primary constructor can get a different accessibility than its type?

### Conclusion
No. There is no elegant way to address this. This is a fine example of a scenario where developers should just fall back to normal constructor syntax. With the previous decisions above, we’ve done our best to make sure that that cliff isn’t too steep.

## Separate doc comments for field parameters and their fields
Doc comments for a primary constructor parameter apply to the parameter. If the parameter is a field parameter, there is no way to add a doc comment that goes on the field itself. Should there be?

### Conclusion
No. If the field needs separate doc comments, it should just be declared as a normal field. With the introduction of initialization scopes above, this is now not only possible but easy.

## Null propagating operator associativity
What does the following mean?

``` c#
var x = a?.b.c;
```

People gravitate to two interpretations, which each side maintains is perfectly intuitive and the only thing that makes sense.

One interpretation is that `?.` is an operator much like `.`. It is left associative, and so the meaning of the above is roughly the same as

``` c#
var x = ((var tmp = a) == null ? null : tmp.b).c;
```

In other words, we access `b` only if `a` is not null, but `c` is accessed regardless. This is obviously likely to lead to a null reference exception; after all the use of the null propagating operator indicates that there’s a likelihood that `a` is null. So advocates of the “left associative” interpretation would put a diagnostic on the code above, warning that this is probably bad, and pushing people to write, instead:

``` c#
var x = a?.b?.c;
```

With a null-check again before accessing `c`.

The other interpretation has been called “right associative”, but that isn’t exactly right (no pun intended): better to call it “short circuiting”. It holds that the null propagating operator should short circuit past subsequent member access (and invocation and indexing) when the receiver is null, essentially pulling those subsequent operations into the conditional:

``` c#
var x = ((var tmp = a) == null ? null : tmp.b.c);
```

There are long discussions about this, which I will no attempt to repeat here. The “short circuiting” interpretation is slightly more efficient, and probably more useful. On the other hand it is more complicated to fit into the language, because it needs to “suck up” subsequent operations in a way those operations aren’t “used to”: since when would the evaluation of `e.x` not necessarily lead to `x` being accessed on `e`? So we’d need to come up with alternative versions of remote access, indexing and invocation that can represent being part of a short-circuited chain following a null propagating operator.

### Conclusion
Despite the extra complexity and some disagreement on the design team, we’ve settled on the “short circuiting” interpretation.


================================================
FILE: meetings/2014/LDM-2014-05-07.md
================================================
# C# Language Design Notes for May 7, 2014

## Agenda
1.	protected and internal <_feature cut – not worth the confusion_>
2.	Field parameters in primary constructors <_feature cut – we want to keep the design space open_>
3.	Property declarations in primary constructors <_interesting but not now_>
4.	Typeswitch <_Not now – more likely as part of a future more general matching feature_>

## protected and internal
Protected and internal was never a feature we were super enthusiastic about. The CLR supports it and it seemed reasonable to surface it in the language. However, the syntactic options are not great. For every suggestion there are significant and good reasons why it doesn’t work. The community has been incredibly helpful in its creativity about names, as well as in pointing out their flaws.

### Conclusion
We won’t do this feature. Guidance for the scenarios it addresses will be to use `internal`: the most important aspect is to hide the member from external consumers of the assembly. The `protected` aspect is more of a software engineering thing within the team. You could imagine at some point adding the protected aspect as an attribute, either recognized by the compiler or respected by a custom diagnostic.

## Field parameters in primary constructors
Now that we’ve added the initialization scope to classes, it is no longer a problem to have primary constructor parameters with the same name as members. This removes most of the motivation for having the field parameters feature, where an explicit accessibility modifier on a parameter would indicate that there should additionally be a field of that name.

### Conclusion
As the next topic demonstrates, there are more interesting things to consider using this design space for in the future. Let’s not occupy it now with this relatively unimportant feature. It is fine that people have to declare their fields explicitly.

## Property declarations in primary constructors
While declaration of fields in the primary constructor parameter list is of limited value, it is very often the case that a constructor parameter is accompanied by a corresponding property. It might be nice if there was a shorthand for this. You could imagine very terse class declarations completely without bodies in some cases.

A hurdle here is the convention that parameters are `camelCase` (start with lower case) and public properties are `PascalCase` (start with upper case). To be general, we’d need for each parameter to give not one but two names – something like this:
``` c#
public class Point(int x: X, int y: Y);
```
Which would yield public getter-only properties named `X` and `Y` as well as constructor parameters `x` and `y` with which the properties are initialized. It would expand to this:
``` c#
public class Point(int x, int y)
{
   public int X { get; } = x;
   public int Y { get; } = y;
}
```
This syntax looks fairly nice in the above example, but it gets a little unwieldy when the names are longer:
``` c#
public class Person(string firstName: FirstName, string lastName: LastName);
```
Maybe we could live with not having separate parameter names. We could reuse the syntax we’ve just dropped for field parameters and use it for property parameters instead:
``` c#
public class Person(public string FirstName, public string LastName);
```
This would be shorthand for writing
``` c#
public class Person(string FirstName, string LastName)
{
   public string FirstName { get; } = FirstName;
   public string LastName { get; } = LastName;
}
```
Now the parameters would show up as PascalCase. This does not seem like a big deal for new types, but it would mean that most current code couldn’t be moved forward to this syntax without breaking callers who use named arguments.

The implied association of parameter and property could certainly be useful in its own right. You could imagine allowing the use of object initializers to initialize these getter-only properties. Instead of translating it into setter calls, the compiler would know the corresponding constructor parameters to pass the values to:
``` c#
var p = new Person { LastName = "Pascal", FirstName = "Blaise" };
```
Would turn into:
``` c#
var p = new Person("Blaise", "Pascal");
```
Also, in the future, if we were to consider pattern matching or deconstruction features, this association could be helpful.

### Conclusion
We like the idea of providing a shorthand in the primary constructor parameter list for generating simple corresponding properties. However, we are not ready to go down this route just yet. We need to decide on the upper-case/lower-case issue for one thing. We note that primary constructors already provide quite an improvement over what you have to write in C# 5.0. That’s just going to have to be good enough for now.

## Typeswitch
For a long time we’ve had the idea to add a typeswitch feature to C#. In this coming release, VB is seriously looking at expanding its `Select Case` statement to allow matching on types. Syntactically, this seems to fit right in as a natural extension in VB. In C#, maybe not so much: the `switch` statement is quite restrictive and only a little evolved from C’s original jump table oriented design. It doesn’t easily accommodate such a different form of case condition.

So if we were to add typeswitching capabilities to C#, we most likely would do it as a new feature with its own syntax. Options range from a switch-like construct with blocks for each match, to a more expression-oriented style reminiscent of pattern matching in functional languages.

A major point here is that type switching can be seen as a special case of pattern matching. Would we ever add generalized pattern matching to C#? It certainly seems like a reasonable possibility. If so, then we should think of any typeswitching feature in that light: it needs to have the credible ability to “grow up” into a pattern matching feature in the future.

### Conclusion
We’ve looked some at this, trying to imagine what a pattern matching future would look like. We have some great ideas, but we are not confident that we can map them out at this point to an extent where we would trust a current typeswitch design to fit well with it. And we do not have capacity to design and implement the full feature set in the current round. 

Let’s rather wait with the whole package and see if we can attack it in one go in the future.



================================================
FILE: meetings/2014/LDM-2014-05-21.md
================================================
# C# Language Design Notes for May 21, 2014

## Agenda
1.	Limit the nameof feature? <_keep current design_>
2.	Extend params IEnumerable? <_keep current design_>
3.	String interpolation <_design nailed down_>

## Limit the nameof feature?
The current design of the `nameof(x)` feature allows for the named entity to reference entities that are not uniquely identified by the (potentially dotted) name given: methods overloaded on signature, and types overloaded on generic arity.

This was rather the point of the feature: since you are only interested in the name, why insist on binding uniquely to just one symbol? As long as there’s at least one entity with the given name, it seems fine to yield the name without error. This sidesteps all the issues with the mythical `infoof()` feature (that would take an entity and return reflective information for it) of coming up with language syntax to uniquely identify overloads. (Also there’s no need to worry about distinguishing generic instantiations from uninstantiated generics, etc.: they all have the same name).

The design, however, does lead to some interesting challenges for the tooling experience: 
``` c#
public void M();
public void M(int i);
public void M(string s);
WriteLine(nameof(M)); // writes the string "M"
```
Which definition of `M` should “Go To Definition” on `M` go to? When does renaming an overload cause a rename inside of the `nameof`? Which of the overloads does the occurrence of `nameof(M)` count as a reference to? Etc. The ambiguity is a neat trick at the language level, but a bit of a pain at the tooling level.

Should we limit the application of `nameof` to situations where it is unambiguous?

### Conclusion
No. Let’s keep the current design. We can come up with reasonable answers for the tooling challenges. Hobbling the feature would hurt real scenarios.

## Extend params IEnumerable?
By current design, params is extended to apply to `IEnumerable<T>` parameters. The feature still works by the call site generating a `T[]` with the arguments in it; but that array is of course available inside the method only as an `IEnumerable<T>`.

It has been suggested that we might as well make this feature work for other generic interfaces (or even all types) that arrays are implicitly reference convertible to, instead of just `IEnumerable<T>`.

It would certainly be straightforward to do, though there are quite a lot of such types. We could even infer an element type for the array from the passed-in arguments for the cases where the collection type does not have an element type of its own.

On the other hand, it is usually bad practice for collection-expecting public APIs to take anything more specific than `IEnumerable<T>`. That is especially true if the API is not intending to modify the collection, and no meaningful params method would do so: after all, if your purpose is to cause a side effect on a passed-in collection, why would you give the caller the option not to pass one?

### Conclusion
Params only really makes sense on `IEnumerable<T>`. If we were designing the language from scratch today we wouldn’t even have params on arrays, but only on `IEnumerable<T>`. So let’s keep the design as is.

## String interpolation
There have been a number of questions around how to add string interpolation to C#, some a matter of ambition versus simplicity, some just a matter of syntax. In the following we settle on these different design aspects.

### Safety
Concatenation of strings with contents of variables has a long tradition for leading to bugs or even attack vectors, when the resulting string is subsequently parsed up and used as a command. Presumably if you make string concatenation easier, you are more vulnerable to such issues – or at least, by having a dedicated string interpolation features, you have a natural place in the language to help address such problems.

Consequently, string interpolation in the upcoming EcmaScript 6 standard allows the user to indicate a function which will be charged with producing the result, based on compiler-generated lists of string fragments and expression results to be filled in. A given trusted function can prevent SQL injection or ensure the well-formedness of a URI.

#### Conclusion
We don’t think accommodating custom interpolators in C# is the sweet spot at this point. Most people are probably just looking for simpler and more readable syntax for filling out holes in strings. However, as we settle on syntax we should keep an eye on our ability to extend for this in the future.

### Culture
In .NET there’s a choice between rendering values in the current culture or an invariant culture. This determines how common values such as dates and even floating point numbers are shown in text. The default is current culture, which even language-recognized functions such as `ToString()` make use of.

Current culture is great if what you’re producing is meant to be read by humans in the same culture as the program is run in. If you get more ambitious than that with human readers, the next step up is to localize in some more elaborate fashion: looking up resources and whatnot. At that point, you are reaching for heavier hammers than the language itself should probably provide.

There’s an argument that when a string is produced for machine consumption it is better done in the invariant culture. After all, it is quite disruptive to a comma-separated list of floating point values if those values are rendered with commas instead of dots as the decimal point!

Should a string interpolation feature default to current or invariant culture, or maybe provide a choice?

#### Conclusion
We think this choice has already been made for us, with the language and .NET APIs broadly defaulting to current culture. That is probably the right choice for most quick-and-easy scenarios. If we were to accommodate custom interpolators in the future, there could certainly be one for culture-invariant rendering.

### Syntax
The general format is strings with “holes”, the holes containing expressions to be “printed” in that spot. We’d like the syntax to stress the analogy to `String.Format` as much as possible, and we therefore want to use curly braces `{…}` in the delimiting of holes. We’ll return to what exactly goes in the curly braces, but for now there is one central question: how do we know to do string interpolation at all?

There are two approaches we can think of:
1.	Provide new syntax around the holes
2.	Provide new syntax around the string itself

To the first approach, we previously settled on escaping the initial curly brace of each hole to mean this was a string interpolation hole, and the contents should be interpreted as expression syntax:
``` c#
"Hello, \{name}, you have \{amount} donut{s} left."
```
Here, `name` and `amount` refer to variables in scope, whereas `{s}` is just part of the text.
This has a few drawbacks. It doesn’t look that much like a format string, because of the backslash characters in front of the curlies. You also need to visually scan the string to see if it is interpolated. Finally there’d be no natural place for us to indicate a custom interpolation function in the future.

An example of the second approach would be to add a prefix to the string to trigger interpolation, e.g.:
``` c#
$"Hello, {name}, you have {amount} donut\{s\} left."
```
Now the holes can be expressed with ordinary braces, and just like format strings you have to escape braces to actually get them in the text (though we are eager to use backslash escapes instead of the double braces that format strings use). You can see up front that the string is interpolated, and if we ever add support for custom interpolators, the function can be put immediately before or after the `$`; whichever we decide:
``` c#
LOC$"Hello, {name}, you have {amount} donut\{s\} left."
SQL$"…"
URI$"…"
```
The prefix certainly doesn’t have to be a `$`, but that’s the character we like best for it. 

We don’t actually have to do it with a prefix. JavaScript is going to use back ticks to surround the string. But prefix certainly seems better than yet another kind of string delimiter.

#### Conclusion
The prefix approach seems better and more future proof. We are happy to use `$`. It wouldn’t compose with the `@` sign used for verbatim strings; it would be either one or the other.

### Format specifiers
Format strings for `String.Format` allow various format specifiers in the placeholders introduced by commas and colons. We could certainly allow similar specifiers in interpolated strings. The semantics would be for the compiler to just turn an interpolated string into a call to `String.Format`, passing along any format specifiers unaltered:
``` c#
$"Hello, {name}, you have {amount,-3} donut\{s\} left."
```
This would be translated to
``` c#
String.Format("Hello, {0}, you have {1,-3} donut{{s}} left.", name, amount)
```
(Note that formatting of literal curlies needs to change if we want to keep our backslash escape syntax, which, tentatively, we do).
The compiler would be free to not call `String.Format`, if it knows how to do things more optimally. This would typically be the case when there are no format specifiers in the string.

#### Conclusion
Allow all format specifiers that are allowed in the format strings of `String.Format`, and just pass them on.

### Expressions in the holes
The final – important – question is which expressions can be put between the curly braces. In principle, we could imagine allowing almost any expression, but it quickly gets weird, both from a readability and from an implementation perspective. What if the expression itself has braces or strings in it? We wouldn’t be able to just lex our way past it (when to stop?), and similarly a reader, even with the help of colorization, would get mightily confused about what gets closed out when exactly.

Additionally the choice to allow format specifiers limits the kinds of expressions that can unambiguously precede those. 
``` c#
$"{a as b ? – c : d}" // ?: or nullable type and format specifier?
```
The other extreme is to allow just a very limited set of expressions. The common case is going to be simple variables anyway, and anything can be expressed by first assigning into variables and then using those in the string.

#### Conclusion
We want to be quite cautious here, at least to begin with. We can always extend the set of expressions allowed, but for now we want to be close to the restrictive extreme and allow only simple and dotted identifiers.




================================================
FILE: meetings/2014/LDM-2014-07-09.md
================================================
# C# Language Design Notes for July 9, 2014

## Agenda
1.	Detailed design of nameof <_details settled_>
2.	Design of #pragma warning extensions <_allow identifiers_>

## Details of nameof
The overall design of `nameof` was decided in the design meeting on [Oct 7, 2013](https://roslyn.codeplex.com/discussions/552376). However, a number of issues weren’t addressed at the time.

### Syntactic ambiguity
The use of `nameof(…)` as an expression can be ambiguous, as it looks like an invocation. In order to stay compatible, if there’s an invokable `nameof` in scope we’ll treat it as an invocation, regardless of whether that invocation is valid. This means that in those cases there is no way to apply the nameof operator. The recommendation of course will be to get rid of any use of `nameof` as an identifier, and we should think about having diagnostics helping with that.

###	Which operands are allowed?
The symbols recognized in a nameof expression must represent locals, range variables, parameters, type parameters, members, types or namespaces. Labels and preprocessor symbols are not allowed in a nameof expression.

In general, free-standing identifiers are looked up like simple names, and dotted rightmost identifiers are looked up like member access. It is thus an error to reference locals before their declaration, or to reference inaccessible members. However, there are some exceptions:

_All members are treated as if they were static members._ This means that instance members are accessed by dotting off the type rather than an instance expression. It also means that the accessibility rules around protected instance members are the simpler rules that apply to static members.

_Generic types are recognized by name only._ Normally there needs to be a type parameter list (or at least dimension specifier) to disambiguate, but type parameter lists or dimension specifiers are not needed, and in fact not allowed, on the rightmost identifier in a nameof.

_Ambiguities are not an error._ Even if multiple entities with the same name are found, nameof will succeed. For instance, if a property named `M` is inherited through one interface and a method named `M` is inherited through another, the usual ambiguity error will not occur.

### The referenced set
Because ambiguities are allowed, a nameof operator can reference a set of different entities at the same time. The precise set of referenced entities in the presence of ambiguity can be loosely defined as “those it would be ambiguous between”. Thus, shadowed members or other entities that wouldn’t normally be found by lookup, e.g. because they are in a base class or an enclosing scope of where an entity is found, will not be part of the referenced set.

The notion of referenced set has little importance for the language-level semantics, but is important for the tooling experience, e.g. for refactorings, go-to-definition, etc.
Reference to some entities, e.g. obsolete members, `Finalize` or ‘`op_`’ methods, is normally an error. However, it is not an error in `nameof(…)` unless _all_ members of the referenced set would give an error. If all non-error references give warnings, then a warning is given.

### The resulting string
C# doesn’t actually have a notion of canonical name. Instead, equality between names is currently defined directly _between_ names that may contain special symbols.

For `nameof(… i)` we want the resulting string to be the identifier `I` given, except that formatting characters are omitted, and Unicode escapes are resolved. Also, any leading `@` is removed.

In the case of aliases, this means that those are not resolved to their underlying meaning: the identifier is that of the alias itself.

As a result, the meaning of the identifier is always only used to check if it is valid, never to decide what the resulting string is. There is no semantic component to determining the result of a nameof operator, only to determining if it is allowed.

## Pragma warning directives
Now that custom diagnostics are on their way, we want to allow users to turn these on and off from source code, just as we do with the compiler’s own diagnostics today. To allow this, we need to extend the model of how a diagnostic is identified: today a number is used, but that is not a scalable model when multiple diagnostic providers are involved.

Instead the design is that diagnostics are identified by an identifier. For compatibility the C# compiler’s own diagnostics can still be referenced with a number, but can also be referred to with the pattern `CS1234`:
``` c#
#pragma warning disable AsyncCoreSet
#pragma warning disable CS1234
```



================================================
FILE: meetings/2014/LDM-2014-08-27.md
================================================
# C# Design Notes for Aug 27, 2014

## Agenda
The meeting focused on rounding out the feature set around structs.
1.	Allowing parameterless constructors in structs <_allow, but some unresolved details_>
2.	Definite assignment for imported structs <_revert to Dev12 behavior_>

## Parameterless constructors in structs
Unlike classes, struct types cannot declare a parameterless constructor in C# and VB today. The reason is that the syntax `new S()` in C# has historically been reserved for producing a zero-initialized instance of the struct. VB.Net has always had an alternative syntax for that (`Nothing`) and C# 2.0 also added one: `default(T)`. So the `new S()` syntax is no longer necessary for this purpose.

It is possible to define parameterless constructors for structs in IL, but neither C#, VB or F# allow you to. All three languages have mostly sane semantics when consuming one, though, _mostly_ having `new S()` call the constructor instead of zero-initializing the struct (except in some corner cases visited below).

Not being able to define parameterless constructors in structs has always been a bit of a pain, and now that we’re adding initializers to structs it becomes outright annoying.

### Conclusion
We want to add the ability to declare explicit public parameterless constructors in structs, and we also want to think about reducing the number of occurrences of `new S()` that produce a default value. In the following we explore details and additional proposals.

### Accessibility
C#, VB and F# will all call an accessible parameterless constructor if they find one. If there is one, but it is not accessible, C# and VB will backfill `default(T)` instead. (F# will complain.)

It is problematic to have successful but different behavior of `new S()` depending on where you are in the code. To minimize this issue, we should make it so that explicit parameterless constructors have to be public. That way, if you want to replace the “default behavior” you do it everywhere.

#### Conclusion
Parameterless constructors will be required to be public.

### Compatibility
Non-generic instantiation of structs with (public) parameterless constructors does the right thing in all three languages today. With generics it gets a little more subtle. All structs satisfy the `new()` constraint. When `new T()` is called on a type parameter `T`, the compiler _should_ generate a call to `Activator.CreateInstance` – and in VB and F# it does. However, C# tries to be smart, discovers at runtime that `T` is a struct (if it doesn’t already know from the `struct` constraint), and emits `default(T)` instead!

``` c#
public T M<T>() where T: new() { return new T(); }
```

Clearly we should remove this “optimization” and always call `Activator.CreateInstance` in C# as well. This is a bit of a breaking change, in two ways. Imagine the above method is in a library:

1.	The more obvious – but also more esoteric – break is if people today call the library with a struct type (written directly in IL) which has a parameterless constructor, yet they depend on the library _not_ calling that parameterless constructor. That seems extremely unlikely, and we can safely ignore this aspect.
2.	The more subtle issue is if such a library is not recompiled as we start populating the world with structs with parameterless constructors. The library is going to be wrongly not calling those constructors until someone recompiles it. But if it’s a third party library and they’ve gone out of business, no-one ever will.

We believe even the second kind of break is relatively rare. The `new()` constraint isn’t used much. But it would be nice to validate.

#### Conclusion
Change the codegen for generic `new T()` in C# but try to validate that the pattern is rare in known code.

### Default arguments
For no good reason C# allows `new` expressions for value types to occur as default arguments to optional parameters:

``` c#
void M(S s = new S()){ … }
```

This is one place where we cannot (and do not) call a parameterless constructor even when there is one. This syntax is plain bad. It suggests one meaning but delivers another.

We should do what we can (custom diagnostic?) to move developers over to use `default(S)` with existing types. More importantly we should not allow this syntax at all when `S` has a parameterless constructor. This would be a slight breaking change for the vanishingly rare IL-authored structs that do today, but so be it.

#### Conclusion
Forbid `new S()` in default arguments when `S` has a parameterless constructor, and consider a custom diagnostic when it doesn’t. People should use `default(S)` instead.

### Helpful diagnostic
In general, with this change we are trying to introduce more of a distinction between default values and constructed values for structs. Today it is very blurred by the use of `new S()` for both meanings.

Arguably the use of `new S()` to get the default value is fine as long as `S` does not have any explicit constructors. It can be viewed a bit like making use of the default constructor in classes, which gets generated for you if you do not have _any_ explicit constructors.

The confusion is when a struct type “intends” to be constructed, by advertising one or more constructors. Provided that none of those is parameterless, `new S()` _still_ creates an unconstructed default value. This may or may not be the intention of the calling code. Oftentimes it would represent a bug where they meant to construct it (and run initializers and so forth), but the lack of complaint from the compiler caused them to think everything was all right.

Occasionally a developer really does want to create an uninitialized value even of a struct that has constructors. In those cases, though, their intent would be much clearer if they used the `default(S)` syntax instead. 

It therefore seems that everyone would be well served by a custom diagnostic that would help “clear up the confusion” as it were, by
* Flagging occurrences of `new S()` where `S` has constructors but not a parameterless one
* Offering a fix to change to `default(T)`, as well as fixes to call the constructors

This would help identify subtle bugs where they exist, and make the developer’s intent clearer when the behavior is intentional.

The issue of course is how disruptive such a diagnostic would be to existing code. Would it be so annoying that they would just turn it off? Also, is the above assumption correct, that the occurrence of any constructor means that the library author intended for a constructor to always run?

#### Conclusion
We are cautiously interested in such a diagnostic, but concerned that it would be too disruptive. We should evaluate its impact on current code.

### Chaining to the default constructor when there’s a parameterless one
A struct constructor must ensure that the struct is definitely assigned. It can do so by chaining to another constructor or by assigning to all fields.

For structs with auto-properties there is an annoying fact that you cannot assign to the underlying field because its name is hidden, and you cannot assign to the setter, because you are not allowed to invoke a function member until the whole struct is definitely assigned. Catch 22!

People usually deal with this today by chaining to the default constructor – which will zero-initialize the entire struct. If there is a user-defined parameterless constructor, however, that will not work. (Especially not if that is the constructor you are trying to implement!)

There is a workaround. Instead of writing
``` c#
S(int x): this() { this.X = x; }
```
You can make use of the fact that in a struct, `this` is an l-value:
``` c#
S(int x) { this = default(S); this.X = x; }
```
It’s not pretty, though. In fact it’s rather magical. We may want to consider adding an alternative syntax for zero-initializing from a constructor; e.g.:
``` c#
S(int x): default() { this.X = x; }
```
However, it is also worth noting that auto-properties themselves are evolving. You can now directly initialize their underlying field with an initializer on the auto-property. And for getter-only auto-properties, assignment in the constructor will also directly assign the underlying field. So maybe problem just isn’t there any longer. You can just zero-initialize the auto-properties directly:
``` c#
public int X { get; set; } = 0;
```
Now the definite assignment analysis will be happy when you get to running a constructor body.

#### Conclusion
Do nothing about this right now, but keep an eye on the issue.

### Generated parameterless constructors
The current rule is that initializers are only allowed if there are constructors that can run them. This seems reasonable, but look at the following code:

``` c#
struct S 
{
	string label = "<unknown>";
	bool pending = true;
	public S(){}
	…
}
```

Do we _really_ want to force people to write that trivial constructor? Had this been a class, they would just have relied on the compiler-generated default constructor. 

It is probably desirable to at least do what classes do and generate a default constructor when there are no other constructors. Of course we wouldn’t generate one when there are no initializers either: that would be an unnecessary (and probably slightly breaking) change over what we do today, as the generated constructor would do exactly the same as the default `new S()` behavior anyway.

A question though is if we should generate a parameterless constructor to run initializers even if there are also parameterful ones. After all, don’t we want to ensure that initializers get run in as many cases as possible?

This seems somewhat attractive, though it does mean that a struct with initializers doesn’t get to choose _not_ to have a generated parameterless constructor that runs the initializers.

Also, in the case that there’s a primary constructor it becomes uncertain what it would mean for a parameterless constructor to run the initializers: after all they may refer to primary constructor parameters that aren’t available to the parameterless constructor:
``` c#
struct Name(string first, string last)
{	
	string first = first;
	string last = last;
}
```
How is a generated parameterless constructor supposed to run those initializers? To make this work, we would probably have to make the parameterless constructor chain to the primary constructor (all other constructors must chain to the primary constructor), passing _default values_ as arguments. 

Alternatively we could require that all structs with primary constructors _also_ provide a parameterless constructor. But that kind of defeats the purpose of primary constructors in the first place: doing the same with less code.

In all we seem to have the following options:
1. Don’t generate anything. If you have initializers, you must also provide at least one constructor. The only change from today’s design is that one of those constructors can be parameterless.
2. Only generate a parameterless constructor if there are no other constructors. This most closely mirrors class behavior, but it may be confusing that adding an explicit constructor “silently” changes the meaning of `new S()` back to zero-initialization. (The above diagnostic would help with that, though).
3. Generate a parameterless constructor only when there is not a primary constructor and
    a. Still fall back to zero-initialization for new S() in this case
    b. Require a parameterless constructor to be explicitly specified
    This seems to introduce an arbitrary distinction between primary constructors and other constructors that prevents easy refactoring back and forth between them.
4. Generate a parameterless constructor even when there is a primary constructor
    a. using default values and/or
    b. some syntax to provide the arguments as part of the primary constructor
    This seems overly magical, and again treats primary constructors more differently than was the intent with their design.

#### Conclusion
This is a hard one, and we didn’t reach agreement. We probably want to do at least option 2, since part of our goal is for structs to become more like classes. But we need to think more about the tradeoffs between that and the more drastic (but also more helpful?) approaches.

## Definite assignments for imported structs
Unlike classes, private fields in structs do need to be observed in various ways on the consumer side – they cannot be considered entirely an implementation detail.

In particular, in order to know if a struct is definitely assigned we need to know if its fields have all been initialized. For inaccessible fields, there is no sure way to do that piecemeal, so if such inaccessible fields exist, the struct-consuming code must insist that the struct value as a whole has been constructed or otherwise initialized.

So the key is to know if the struct has inaccessible fields. The native compiler had a long-running bug that would cause it to check imported structs for inaccessible fields _only_ where those fields were of value type! So if the struct had only a private field of a reference type, the compiler would fail to ensure that it was definitely assigned.

In Roslyn we started out implementing the specification, which was of course stricter and turned out to break some code (that was buggy and should probably have been fixed). Instead we then went to the opposite extreme and just stopped ensuring definite assignment of these structs altogether. This lead to its own set of problems, primarily in the form of a new set of bugs that went undetected because of the laxer rules.

Ideally we would go back to implementing the spec. This would break old code, but have the best experience for new code. If we had a “quirks” mode approach, we could allow e.g. the lang-version flag to be more lax on older versions. Part of migrating a code base to the new version of the language would involve fixing this kind of issue.

### Conclusion
Unfortunately we do not have the notion of a quirks mode. Like a number of issues before, this one alone does not warrant introducing one – after all, it is a new kind of upgrade tax on customers. We should compile a list of things we would do if we had a quirks mode, and evaluate if the combined value would be enough to justify it.

Definite assignment for structs should be on that list. In the meantime however, the best we can do is to revert to the behavior of the native compiler, so that’s what we’ll do.



================================================
FILE: meetings/2014/LDM-2014-09-03.md
================================================
# C# Design Notes for Sep 3, 2014

Quote of the day: “It’s a design smell. But it’s a good smell.”

## Agenda
The meeting focused on rounding out the design of declaration expressions
1.	Removing “spill out” from declaration expressions in simple statements <_yes, remove_>
2.	Same name declared in subsequent else-if’s <_condition decls out of scope in else-branch_>
3.	Add semicolon expressions <_not in this version_>
4.	Make variables in declaration expressions readonly <_no_>

## “Spill out”
The scope rules for variables introduced in declaration expressions are reasonably regular: the scope of such a variable extends to the nearest enclosing statement, and like all local variables, it may be used only after it has been defined, textually.

We did make a couple of exceptions, though: an expression-statement or a declaration-statement does _not_ serve as a boundary for such a variable – instead it “spills out” to the directly enclosing block – if there is one.

Similarly, a declaration expression in one field initializer is in scope for neighboring field initializers (as long as they are in the same part of the type declaration).

This was supposed to enable scenarios such as this:
``` c#
GetCoordinates(out var x, out var y);
… // use x and y;
```

to address the complaint that it is too much of a hassle to use out and ref parameters. But we have a nagging suspicion that this scenario – pick up the value in one statement and use it in the next – is not very common. Instead the typical scenario looks like this:
``` c#
if (int.TryParse(s, out int i)) { … i … }
```
Where the introduced local is used in the _same_ statement as it is declared in.

Outside of conditions, probably the most common use is the inline common-subexpression refactoring, where the result of an expression is captured into a variable the first time it is used, so the variable can be applied to the remaining ones:
``` c#
Console.WriteLine("Result: {0}", (var x = GetValue()) * x);
```

The spill-out is actually a bit of a nuisance for the somewhat common scenario of passing dummies to ref or out parameters that you don’t need (common in COM interop scenarios), because you cannot use the same dummy names in subsequent statements.

From a rule regularity perspective, the spilling is quite complicated to explain. It would be a meaningful simplification to get rid of it. While complexity of spec’ing and implementing shouldn’t stand in the way of a good feature, it is often a smell that the design isn’t quite right.

### Conclusion
Let’s get rid of the spilling. Every declaration expression is now limited in scope to it nearest enclosing statement. We’ll live with the (hopefully) slight reduction in usage scenarios.

## Else-if’s
Declaration expressions lend themselves particularly well to a style of programming where an if/else-if chain goes through various options, each represented by a variable declared in a condition, using those variables in the then-clause:
``` c#
if ((var i = o as int?) != null) { … i … }
else if ((var s = o as string) != null) { … s … }
else if …
```
This particular pattern _looks_ like a chain of subsequent options, and even indents like that, but linguistically the else clauses are nested. For that reason, with our current scope rules the variable `I` introduced in the first condition is in scope in all the rest of the statement – even though it is only meaningful and interesting in the then-branch. In particular, it blocks another variable with the same name from being introduced in a subsequent condition, which is quite annoying.

We do want to solve this problem. There is no killer option that we can think of, but there are a couple of plausible approaches:

1. Change the scope rules so that variables declared in the condition of an if are in scope in the then-branch  but not in the else-branch
2. Remove the restriction that locals cannot be shadowed by other locals
3. Do something very scenario specific

### Changing the scope rules
Changing the scope rules would have the unfortunate consequence of breaking the symmetry of if-statements, so that 
``` c#
if (b) S1 else S2
```
No longer means exactly the same as
``` c#
if (!b) S2 else S1
```
It kind of banks on the fact that the majority of folks who would introduce declaration expressions in a condition would do so for use in the then-branch only. That certainly seems to be likely, given the cases we have seen (type tests, uses of the `Try…` pattern, etc.). But it still may be surprising to some, and downright bothersome in certain cases.

Worse, there may be tools that rely on this symmetry principle. Refactorings to swap then and else branches (negating the condition) abound. These would no longer always work.

Moreover, of course, this breaks with the nice simple scoping principle for declaration expressions that we just established above: that they are bounded (only) by their enclosing statement.

### Removing the shadowing restriction
Since C# 1.0, it has been forbidden to shadow a local variable or parameter with another one. This is seen as one of the more successful rules of hygiene in C# - it makes code safe for refactoring in many scenarios, and just generally easier to read.

There are existing cases where this rule is annoying:
``` C#
task.ContinueWith(task => … task …); // Same task! Why can’t I name it the same?
```
Here it seems the rule even runs counter to refactoring, because you need to change every occurrence of the name when you move code into a lambda.

Lifting this restriction would certainly help the else-if scenario. While previous variables would still be in scope, you could now just shadow them with new ones if you choose.

If you do not choose to use the same name, however, the fact that those previous variables are in scope may lead to confusion or accidental use.

More importantly, are we really ready to part with this rule? It seems to be quite well appreciated as an aid to avoid subtle bugs.

### Special casing the scenario
Instead of breaking with general rules, maybe we can do something very localized? Some combination of the two?
It would have to work both in then and else branches; otherwise, it would still break the if symmetry, and be as bad as the first option.

We could allow only variables introduced in conditions of if-statements to be shadowed only by other variables introduced in conditions of if-statements?

This might work, but seems inexcusably ad-hoc, and is almost certain to cause a bug tail in many tools down the line, as well as confusion when refactoring code or trying to experiment with language semantics. 

### Conclusion
It seems there truly is no great option here. However, we’d rather solve the problem with a wart or two than not address it at all. On balance, option 1, the special scope rule for else clauses, seems the most palatable, so that’s what we’ll do.

## Semicolon expressions
We previously proposed a semicolon operator, to be commonly used with declaration expressions, to make “let-like” scenarios a little nicer:
``` c#
Console.WriteLine("Result: {0}", (var x = GetValue(); x * x));
```
Instead of being captured on first use, the value is now captured first, _then_ used multiple times.

We are not currently on track to include this feature in the upcoming version of the language. The question is; should we be? There’s an argument that declaration expressions only come to their full use when they can be part of such a let-like construct. Also, there are cases (such as conditional expressions) where you cannot just declare the variable on first use, since the use is in a branch separate from later uses.

Nevertheless, it might be rash to say that this is our let story. Is this how we want let to look like in C#? We don’t easily get another shot at addressing the long-standing request for a let-like expression. It probably needs more thought than we have time to devote to it now.

### Conclusion
Let’s punt on this feature and reconsider in a later version.

## Should declaration expression variables be mutable?
C# is an imperative language, and locals are often used in a way that depends on mutating them sometime after initialization. However, you could argue that this is primarily useful when used across statements, whereas it generally would be a code smell to have a declaration that’s only visible _inside_ one statement rely on mutation.

This may or may not be the case, but declaration _expressions_ also benefit from a strong analogy with declaration _statements_. It would be weird that `var s = GetString()` introduces a readonly variable in one setting but not another. (Note: it does in fact introduce a readonly variable in a few situations, like foreach and using statements, but those can be considered special).

### Conclusion
Let’s keep declaration expressions similar to declaration statements. It is too weird if a slight refactoring causes the meaning to change. It may be worth looking at adding readonly locals at a later point, but that should be done in an orthogonal way.


================================================
FILE: meetings/2014/LDM-2014-10-01.md
================================================
There were two agenda items...
1. Assignment to readonly autoprops in constructors (we fleshed out details)
2. A new compiler warning to prevent outsiders from implementing your interface? (no, leave this to analyzers)

# Assignment to readonly autoprops in constructors

```cs
public struct S {
   public int x {get;}
   public int y {get; set;}
   public Z z {get;}

   public S() {
      x = 15;
      y = 23;
      z.z1 = 1;
   }
}

public struct Z { int z1; }
```

_What are the rules under which assignments to autoprops are allowed in constructors?_

__Absolute__ We can't be more permissive in what we allow with readonly autoprops than we are with readonly fields, because this would break PEVerify. (Incidentally, PEVerify doesn't check definite assignment in the constructor of a struct; that's solely a C# language thing).

__Overall principle__ When reading/writing to an autoprop, do we go via the accessor (if there is one) or do we bypass it (if there is one) and access the underlying field directly?
_Option1:_ language semantics say the accessor is used, and codegen uses it.
_Option2:_ in an appropriate constructor, when there is a "final" autoprop (either non-virtual, or virtual in a sealed class), access to an autoprop _means_ an access to the underlying field. This meaning is used for definite assignment, and for codegen. Note that it is semantically visible whether we read from an underlying field vs through an accessor, e.g. in `int c { [CodeSecurity] get;}`
_Resolution: Option1_. Under Option2, if you set a breakpoint on the getter of an autoprop, gets of it would not hit the breakpoint if they were called in the constructor which is weird. Also it would be weird that making the class sealed or the autoprop non-virtual would have this subtle change. And things like Postsharper wouldn't be able to inject. All round Option2 is weird and Option1 is clean and expected.

__Definite Assignment__. Within an appropriate constructor, what exactly are the rules for definite assignment? Currently if you try to read a property before _all_ fields have been assigned then it says CS0188 'this' cannot be used before all fields are assignment, but reading a field is allowed so long as merely that field has been assigned. More precisely, within an appropriate constructor, for purposes of definite assignment analysis, when does access of the autoprop behave as if it's an access of the backing field?
_Option1_: never
_Option2_: Only in case of writes to readonly autoprops
_Option3_: In the case of writes to all autoprops
_Option4_: In the case of reads and writes to all autoprops
_Resolution: Option4_. This is the most helpful to developers. You might wonder what happens if it's a virtual autoprop and someone overrides getter or setter in derived types in such a way that would violate the definite assignment assumptions. But for structs there won't be derived types, and for classes the semantics say that all fields are assigned to default(.) so there's no difference.

__Piecewise initialization of structs__. In the code above, do we allow `z.z1 = 15` to assign to the _field_ of a readonly struct autoprop?
_Option1:_ Yes by threating access to "z" for purposes of definite assignment as an access of the underlying field.
_Option2:_ No because in `z.z1` the read of `z` happens via the accessor as per the principle above, and thus returns an rvalue, and hence assignment to `z.z1` can't work. Instead you will have to write `z = new Z(...)`.
_Resolution: Option2_. If we went with Option1, then readonly autoprops would end up being more expressive than settable autoprops which would be odd! Note that in VB you can still write `_z.z1 = 15` if you do want piecewise assignment.

__Virtual__. What should happen if the readonly autoprop is virtual, and its getter is overridden in a derived class?
_Resolution:_ All reads of the autoprop go via its accessor, as is already the case.

__Semantic model__. In the line `x = 15` what should the Roslyn semantic model APIs say for the symbol `x` ?
_Resolution:_ they refer to the property x. Not the backing field. (Under the hood of the compiler, during lowering, if in an appropriate constructor,  for write purposes, it is implicitly transformed into a reference to the backing field). More specifically, for access to an autoprop in the constructor,
1. It should _bind_ to the property, but the property should be treated as a readable+writable (for purposes of what's allowed) in the case of a readonly autoprop.
2. The definite assignment behavior should be as if directly accessing the backing field.
3. It should code gen to the property accessor (if one exists) or a field access (if not).

__Out/ref arguments in C#__. Can you pass a readonly autoprop as an out/ref argument in C#?
_Resolution: No_. For readonly autoprops passed as _ref_ arguments, that wouldn't obey the principle that access to the prop goes via its accessor. For passing readonly autoprops as _out_ arguments with the hope that it writes to the underlying field, that wouldn't obey the principle that we bind to the property rather than the backing field. For writeonly autoprops, they don't exist because they're not useful.

__Static readonly autoprops__ Should everything we've written also work for static readonly autoprops?
_Resolution: Yes._ Note there's currently a bug in the native compiler (fixed in Dev14) where the static constructor of a type G\<T> is able to initialize static readonly fields in specializations of G e.g. `G<T>.x=15;`. The CLR does indeed maintain separate storage locations for each static readonly fields, so `G<int>.g` and `G<string>.g` are different variables. (The native compiler's bug where the static constructor of G could assign to all of them resulted in unverifiable code).

__VB rules in initializers as well as constructors__. VB initializers are allowed to refer to other members of a class, and VB initializers are all executed during construction time. Should everything we've said about behavior in C# constructors also apply to behavior in VB initializers?
_Resolution: Yes_.

__VB copyback for ByRef parameters__. In VB, when you pass an argument to a ByRef parameter, then either it passes it as an lvalue (if the argument was a local variable or field or similar) or it uses "copy-in to a temporary then invoke the method then copy-out from the temporary" (if the argument was a property), or it uses "copy-in to a temporary then invoke the method then ignore the output" (if the argument was an rvalue or a constant). What should happen when you pass a readonly autoprop to a ByRef parameter?
_Option1:_ Emit a compile-time error because copyback is mysterious and bites you in mysterious ways, and this new way is even more mysterious than what was there before.
_Option2:_ Within the constructor/initializers, copy-in by reading via the accessor, and copy-back by writing to the underlying field. Elsewhere, copy-in with no copy-out. Also, just as happens with readonly fields, emit an error if assignment to a readonly autoprop happens in a lambda in a constructor (see code example below)
_Resolution: Option2_. Exactly has happens today for readonly fields. Note incidentally that passing a readonly autoprop to a ByRef parameter will have one behavior in the constructor and initializers (it will do the copy-back), and will silently have different behavior elsewhere (it won't do any copy-back). This too is already the case with readonly fields. On a separate note, developers would like to have feedback in some cases (not constants or COM) where copyback in a ByRef argument isn't done. But that's not a question for the language design meeting.

__VB copyin for writeonly autoprops__. VB tentatively has writeonly autoprops for symmetry, even though they're not useful. What should happen when you pass a writeonly autoprop as a ByRef argument?
_Resolution: Yuck._ This is a stupid corner case. Notionally the correct thing is to read from the backing field, and write via the setter. But if it's easier to just remove support for writeonly autoprops, then do that.

```vb
Class C
    ReadOnly x As Integer = 15

    Public Sub New()
        f(x)
        Dim lambda = Sub()
                         f(x) ' error BC36602: 'ReadOnly' variable
                         ' cannot be the target of an assignment in a lambda expression
                         ' inside a constructor.
                     End Sub
    End Sub
    Shared Sub f(ByRef x As Integer)
        x = 23
    End Sub
End Class
```

We discussed a potential new error message in the compiler.

__Scenario:__ Roslyn ships with ISymbol interface. In a future release it wants to add additional members to the interface. But this will break anyone who implemented ISymbol in its current form. Therefore it would be good to have a way to prevent anyone _else_ from implementing ISymbol. That would allow us to add members without breaking people.

Is this scenario widespread? Presumably, but we don't have data and haven't heard asks for it. There are a number of workarounds today. Some workarounds provide solid code guarantees. Other workarounds provide "suggestions" or "encouragements" that might be enough for us to feel comfortable breaking people who took dependencies where we told them not to.

__Counter-scenario:__ Nevertheless, I want to _MOCK_ types. I want to construct a mock ISymbol myself maybe using MOQ, and pass it to my functions which take in an ISymbol, for testing purposes. I still want to be able to do this. (Note: MOQ will automatically update whenever we add new members to ISymbol, so users of it won't be broken).


__Workarounds__

1. Ignore the problem and just break people.
2. Like COM, solve it by adding new incremental interfaces ISymbol2 with the additional members. As Adam Speight notes below, you can make ISymbol2 inherit from ISymbol.
3. Instead of interfaces, use abstract classes with internal constructors. Or abstract classes but never add abstract methods to it; only virtual methods.
4. Write documentation for the interface, on MSDN or in XML Doc-Comments, that say "Internal class only; do not implement it". We see this for instance on ICorThreadpool.
5. Declare a method on the interface which has an internal type in its signat
Download .txt
gitextract_dhtuocpa/

├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   └── ISSUE_TEMPLATE/
│       ├── config.yml
│       ├── docs-feedback.yml
│       └── proposal_template.md
├── .gitignore
├── CODE-OF-CONDUCT.md
├── Communities.md
├── Design-Process.md
├── Language-Version-History.md
├── README.md
├── meetings/
│   ├── 2013/
│   │   ├── LDM-2013-10-07.md
│   │   ├── LDM-2013-10-21.md
│   │   ├── LDM-2013-11-04.md
│   │   ├── LDM-2013-12-16.md
│   │   └── README.md
│   ├── 2014/
│   │   ├── LDM-2014-01-06.md
│   │   ├── LDM-2014-02-03.md
│   │   ├── LDM-2014-02-10.md
│   │   ├── LDM-2014-04-21.md
│   │   ├── LDM-2014-05-07.md
│   │   ├── LDM-2014-05-21.md
│   │   ├── LDM-2014-07-09.md
│   │   ├── LDM-2014-08-27.md
│   │   ├── LDM-2014-09-03.md
│   │   ├── LDM-2014-10-01.md
│   │   ├── LDM-2014-10-15.md
│   │   └── README.md
│   ├── 2015/
│   │   ├── LDM-2015-01-21.md
│   │   ├── LDM-2015-01-28.md
│   │   ├── LDM-2015-02-04.md
│   │   ├── LDM-2015-02-11.md
│   │   ├── LDM-2015-03-04.md
│   │   ├── LDM-2015-03-10-17.md
│   │   ├── LDM-2015-03-18.md
│   │   ├── LDM-2015-03-24.md
│   │   ├── LDM-2015-03-25-Design-Review.md
│   │   ├── LDM-2015-03-25-Notes.md
│   │   ├── LDM-2015-04-01-08.md
│   │   ├── LDM-2015-04-14.md
│   │   ├── LDM-2015-04-15.md
│   │   ├── LDM-2015-04-22-Design-Review.md
│   │   ├── LDM-2015-05-20.md
│   │   ├── LDM-2015-05-25.md
│   │   ├── LDM-2015-07-01.md
│   │   ├── LDM-2015-07-07.md
│   │   ├── LDM-2015-08-18.md
│   │   ├── LDM-2015-09-01.md
│   │   ├── LDM-2015-09-02.md
│   │   ├── LDM-2015-09-08.md
│   │   ├── LDM-2015-10-07-Design-Review.md
│   │   ├── LDM-2015-11-02-Design-Demo.md
│   │   └── README.md
│   ├── 2016/
│   │   ├── LDM-2016-02-29.md
│   │   ├── LDM-2016-04-06.md
│   │   ├── LDM-2016-04-12-22.md
│   │   ├── LDM-2016-05-03-04.md
│   │   ├── LDM-2016-05-10.md
│   │   ├── LDM-2016-07-12.md
│   │   ├── LDM-2016-07-13.md
│   │   ├── LDM-2016-07-15.md
│   │   ├── LDM-2016-08-24.md
│   │   ├── LDM-2016-09-06.md
│   │   ├── LDM-2016-10-18.md
│   │   ├── LDM-2016-10-25-26.md
│   │   ├── LDM-2016-11-01.md
│   │   ├── LDM-2016-11-15.md
│   │   ├── LDM-2016-11-16.md
│   │   ├── LDM-2016-11-30.md
│   │   ├── LDM-2016-12-07-14.md
│   │   └── README.md
│   ├── 2017/
│   │   ├── CLR-2017-03-23.md
│   │   ├── LDM-2017-01-10.md
│   │   ├── LDM-2017-01-11.md
│   │   ├── LDM-2017-01-17.md
│   │   ├── LDM-2017-01-18.md
│   │   ├── LDM-2017-02-14.md
│   │   ├── LDM-2017-02-15.md
│   │   ├── LDM-2017-02-21.md
│   │   ├── LDM-2017-02-22.md
│   │   ├── LDM-2017-02-28.md
│   │   ├── LDM-2017-03-01.md
│   │   ├── LDM-2017-03-07.md
│   │   ├── LDM-2017-03-08.md
│   │   ├── LDM-2017-03-15.md
│   │   ├── LDM-2017-03-21.md
│   │   ├── LDM-2017-03-28.md
│   │   ├── LDM-2017-03-29.md
│   │   ├── LDM-2017-04-05.md
│   │   ├── LDM-2017-04-11.md
│   │   ├── LDM-2017-04-18.md
│   │   ├── LDM-2017-04-19.md
│   │   ├── LDM-2017-05-16.md
│   │   ├── LDM-2017-05-17.md
│   │   ├── LDM-2017-05-26.md
│   │   ├── LDM-2017-05-31.md
│   │   ├── LDM-2017-06-13.md
│   │   ├── LDM-2017-06-14.md
│   │   ├── LDM-2017-06-27.md
│   │   ├── LDM-2017-06-28.md
│   │   ├── LDM-2017-07-05.md
│   │   ├── LDM-2017-07-26.md
│   │   ├── LDM-2017-08-07.md
│   │   ├── LDM-2017-08-09.md
│   │   ├── LDM-2017-08-14.md
│   │   ├── LDM-2017-08-16.md
│   │   ├── LDM-2017-08-21.md
│   │   ├── LDM-2017-08-23.md
│   │   ├── LDM-2017-08-28.md
│   │   ├── LDM-2017-08-30.md
│   │   ├── LDM-2017-09-25.md
│   │   ├── LDM-2017-09-27.md
│   │   ├── LDM-2017-10-02.md
│   │   ├── LDM-2017-10-04.md
│   │   ├── LDM-2017-10-09.md
│   │   ├── LDM-2017-10-11.md
│   │   ├── LDM-2017-10-16.md
│   │   ├── LDM-2017-10-18.md
│   │   ├── LDM-2017-10-25.md
│   │   ├── LDM-2017-11-06.md
│   │   ├── LDM-2017-11-08.md
│   │   ├── LDM-2017-11-20.md
│   │   ├── LDM-2017-11-27.md
│   │   ├── LDM-2017-11-29.md
│   │   ├── LDM-2017-12-04.md
│   │   ├── LDM-2017-12-06.md
│   │   └── README.md
│   ├── 2018/
│   │   ├── LDM-2018-01-03.md
│   │   ├── LDM-2018-01-10.md
│   │   ├── LDM-2018-01-18.md
│   │   ├── LDM-2018-01-22.md
│   │   ├── LDM-2018-01-24.md
│   │   ├── LDM-2018-01-31.md
│   │   ├── LDM-2018-02-05.md
│   │   ├── LDM-2018-02-07.md
│   │   ├── LDM-2018-02-14.md
│   │   ├── LDM-2018-02-21.md
│   │   ├── LDM-2018-02-26.md
│   │   ├── LDM-2018-02-28.md
│   │   ├── LDM-2018-03-14.md
│   │   ├── LDM-2018-03-19.md
│   │   ├── LDM-2018-03-21.md
│   │   ├── LDM-2018-03-28.md
│   │   ├── LDM-2018-04-02.md
│   │   ├── LDM-2018-04-04.md
│   │   ├── LDM-2018-04-25.md
│   │   ├── LDM-2018-04-30.md
│   │   ├── LDM-2018-05-02.md
│   │   ├── LDM-2018-05-14.md
│   │   ├── LDM-2018-05-21.md
│   │   ├── LDM-2018-05-23.md
│   │   ├── LDM-2018-05-30.md
│   │   ├── LDM-2018-06-04.md
│   │   ├── LDM-2018-06-06.md
│   │   ├── LDM-2018-06-25.md
│   │   ├── LDM-2018-07-09.md
│   │   ├── LDM-2018-07-11.md
│   │   ├── LDM-2018-07-16.md
│   │   ├── LDM-2018-08-20.md
│   │   ├── LDM-2018-08-22.md
│   │   ├── LDM-2018-09-05.md
│   │   ├── LDM-2018-09-10.md
│   │   ├── LDM-2018-09-19.md
│   │   ├── LDM-2018-09-24.md
│   │   ├── LDM-2018-09-26.md
│   │   ├── LDM-2018-10-01.md
│   │   ├── LDM-2018-10-03.md
│   │   ├── LDM-2018-10-10.md
│   │   ├── LDM-2018-10-15.md
│   │   ├── LDM-2018-10-17.md
│   │   ├── LDM-2018-10-22.md
│   │   ├── LDM-2018-10-24.md
│   │   ├── LDM-2018-10-29.md
│   │   ├── LDM-2018-10-31.md
│   │   ├── LDM-2018-11-05.md
│   │   ├── LDM-2018-11-14.md
│   │   ├── LDM-2018-11-28.md
│   │   ├── LDM-2018-12-03.md
│   │   ├── LDM-2018-12-05.md
│   │   ├── LDM-2018-12-12.md
│   │   └── README.md
│   ├── 2019/
│   │   ├── LDM-2019-01-07.md
│   │   ├── LDM-2019-01-09.md
│   │   ├── LDM-2019-01-14.md
│   │   ├── LDM-2019-01-16.md
│   │   ├── LDM-2019-01-23.md
│   │   ├── LDM-2019-02-13.md
│   │   ├── LDM-2019-02-20.md
│   │   ├── LDM-2019-02-25.md
│   │   ├── LDM-2019-02-27.md
│   │   ├── LDM-2019-03-04.md
│   │   ├── LDM-2019-03-06.md
│   │   ├── LDM-2019-03-13.md
│   │   ├── LDM-2019-03-19.md
│   │   ├── LDM-2019-03-25.md
│   │   ├── LDM-2019-03-27.md
│   │   ├── LDM-2019-04-01.md
│   │   ├── LDM-2019-04-03.md
│   │   ├── LDM-2019-04-15.md
│   │   ├── LDM-2019-04-22.md
│   │   ├── LDM-2019-04-24.md
│   │   ├── LDM-2019-04-29.md
│   │   ├── LDM-2019-05-13.md
│   │   ├── LDM-2019-05-15.md
│   │   ├── LDM-2019-07-10.md
│   │   ├── LDM-2019-07-17.md
│   │   ├── LDM-2019-07-22.md
│   │   ├── LDM-2019-08-26.md
│   │   ├── LDM-2019-08-28.md
│   │   ├── LDM-2019-09-04.md
│   │   ├── LDM-2019-09-11.md
│   │   ├── LDM-2019-09-16.md
│   │   ├── LDM-2019-09-18.md
│   │   ├── LDM-2019-10-21.md
│   │   ├── LDM-2019-10-23.md
│   │   ├── LDM-2019-10-28.md
│   │   ├── LDM-2019-10-30.md
│   │   ├── LDM-2019-11-11.md
│   │   ├── LDM-2019-11-13.md
│   │   ├── LDM-2019-11-18.md
│   │   ├── LDM-2019-11-25.md
│   │   ├── LDM-2019-12-11.md
│   │   ├── LDM-2019-12-16.md
│   │   ├── LDM-2019-12-18.md
│   │   └── README.md
│   ├── 2020/
│   │   ├── LDM-2020-01-06.md
│   │   ├── LDM-2020-01-08.md
│   │   ├── LDM-2020-01-15.md
│   │   ├── LDM-2020-01-22.md
│   │   ├── LDM-2020-01-29.md
│   │   ├── LDM-2020-02-03.md
│   │   ├── LDM-2020-02-05.md
│   │   ├── LDM-2020-02-10.md
│   │   ├── LDM-2020-02-12.md
│   │   ├── LDM-2020-02-19.md
│   │   ├── LDM-2020-02-24.md
│   │   ├── LDM-2020-02-26.md
│   │   ├── LDM-2020-03-09.md
│   │   ├── LDM-2020-03-23.md
│   │   ├── LDM-2020-03-25.md
│   │   ├── LDM-2020-03-30.md
│   │   ├── LDM-2020-04-01.md
│   │   ├── LDM-2020-04-06.md
│   │   ├── LDM-2020-04-08.md
│   │   ├── LDM-2020-04-13.md
│   │   ├── LDM-2020-04-15.md
│   │   ├── LDM-2020-04-20.md
│   │   ├── LDM-2020-04-27.md
│   │   ├── LDM-2020-05-04.md
│   │   ├── LDM-2020-05-06.md
│   │   ├── LDM-2020-05-11.md
│   │   ├── LDM-2020-05-27.md
│   │   ├── LDM-2020-06-01.md
│   │   ├── LDM-2020-06-10.md
│   │   ├── LDM-2020-06-15.md
│   │   ├── LDM-2020-06-17.md
│   │   ├── LDM-2020-06-22.md
│   │   ├── LDM-2020-06-24.md
│   │   ├── LDM-2020-06-29.md
│   │   ├── LDM-2020-07-01.md
│   │   ├── LDM-2020-07-06.md
│   │   ├── LDM-2020-07-13.md
│   │   ├── LDM-2020-07-20.md
│   │   ├── LDM-2020-07-27.md
│   │   ├── LDM-2020-08-24.md
│   │   ├── LDM-2020-09-09.md
│   │   ├── LDM-2020-09-14.md
│   │   ├── LDM-2020-09-16.md
│   │   ├── LDM-2020-09-23.md
│   │   ├── LDM-2020-09-28.md
│   │   ├── LDM-2020-09-30.md
│   │   ├── LDM-2020-10-05.md
│   │   ├── LDM-2020-10-07.md
│   │   ├── LDM-2020-10-12.md
│   │   ├── LDM-2020-10-14.md
│   │   ├── LDM-2020-10-21.md
│   │   ├── LDM-2020-10-26.md
│   │   ├── LDM-2020-11-04.md
│   │   ├── LDM-2020-11-11.md
│   │   ├── LDM-2020-11-16.md
│   │   ├── LDM-2020-12-02.md
│   │   ├── LDM-2020-12-07.md
│   │   ├── LDM-2020-12-14.md
│   │   ├── LDM-2020-12-16.md
│   │   └── README.md
│   ├── 2021/
│   │   ├── LDM-2021-01-05.md
│   │   ├── LDM-2021-01-11.md
│   │   ├── LDM-2021-01-13.md
│   │   ├── LDM-2021-01-27.md
│   │   ├── LDM-2021-02-03.md
│   │   ├── LDM-2021-02-08.md
│   │   ├── LDM-2021-02-10.md
│   │   ├── LDM-2021-02-22.md
│   │   ├── LDM-2021-02-24.md
│   │   ├── LDM-2021-03-01.md
│   │   ├── LDM-2021-03-03.md
│   │   ├── LDM-2021-03-10.md
│   │   ├── LDM-2021-03-15.md
│   │   ├── LDM-2021-03-24.md
│   │   ├── LDM-2021-03-29.md
│   │   ├── LDM-2021-04-05.md
│   │   ├── LDM-2021-04-07.md
│   │   ├── LDM-2021-04-12.md
│   │   ├── LDM-2021-04-14.md
│   │   ├── LDM-2021-04-19.md
│   │   ├── LDM-2021-04-21.md
│   │   ├── LDM-2021-04-28.md
│   │   ├── LDM-2021-05-03.md
│   │   ├── LDM-2021-05-10.md
│   │   ├── LDM-2021-05-12.md
│   │   ├── LDM-2021-05-17.md
│   │   ├── LDM-2021-05-19.md
│   │   ├── LDM-2021-05-26.md
│   │   ├── LDM-2021-06-02.md
│   │   ├── LDM-2021-06-07.md
│   │   ├── LDM-2021-06-14.md
│   │   ├── LDM-2021-06-21.md
│   │   ├── LDM-2021-07-12.md
│   │   ├── LDM-2021-07-19.md
│   │   ├── LDM-2021-07-26.md
│   │   ├── LDM-2021-08-23.md
│   │   ├── LDM-2021-08-25.md
│   │   ├── LDM-2021-08-30.md
│   │   ├── LDM-2021-09-01.md
│   │   ├── LDM-2021-09-13.md
│   │   ├── LDM-2021-09-15.md
│   │   ├── LDM-2021-09-20.md
│   │   ├── LDM-2021-09-22.md
│   │   ├── LDM-2021-10-13.md
│   │   ├── LDM-2021-10-20.md
│   │   ├── LDM-2021-10-25.md
│   │   ├── LDM-2021-10-27.md
│   │   ├── LDM-2021-11-01.md
│   │   ├── LDM-2021-11-03.md
│   │   ├── LDM-2021-11-10.md
│   │   ├── LDM-2021-12-01.md
│   │   ├── LDM-2021-12-15.md
│   │   └── README.md
│   ├── 2022/
│   │   ├── LDM-2022-01-03.md
│   │   ├── LDM-2022-01-05.md
│   │   ├── LDM-2022-01-12.md
│   │   ├── LDM-2022-01-24.md
│   │   ├── LDM-2022-01-26.md
│   │   ├── LDM-2022-02-07.md
│   │   ├── LDM-2022-02-09.md
│   │   ├── LDM-2022-02-14.md
│   │   ├── LDM-2022-02-16.md
│   │   ├── LDM-2022-02-23.md
│   │   ├── LDM-2022-02-28.md
│   │   ├── LDM-2022-03-02.md
│   │   ├── LDM-2022-03-09.md
│   │   ├── LDM-2022-03-14.md
│   │   ├── LDM-2022-03-21.md
│   │   ├── LDM-2022-03-23.md
│   │   ├── LDM-2022-03-28.md
│   │   ├── LDM-2022-03-30.md
│   │   ├── LDM-2022-04-06.md
│   │   ├── LDM-2022-04-11.md
│   │   ├── LDM-2022-04-13.md
│   │   ├── LDM-2022-04-18.md
│   │   ├── LDM-2022-04-25.md
│   │   ├── LDM-2022-04-27.md
│   │   ├── LDM-2022-05-02.md
│   │   ├── LDM-2022-05-09.md
│   │   ├── LDM-2022-05-11.md
│   │   ├── LDM-2022-05-23.md
│   │   ├── LDM-2022-06-06.md
│   │   ├── LDM-2022-06-29.md
│   │   ├── LDM-2022-07-13.md
│   │   ├── LDM-2022-07-27.md
│   │   ├── LDM-2022-08-03.md
│   │   ├── LDM-2022-08-10.md
│   │   ├── LDM-2022-08-24.md
│   │   ├── LDM-2022-08-31.md
│   │   ├── LDM-2022-09-21.md
│   │   ├── LDM-2022-09-26.md
│   │   ├── LDM-2022-09-28.md
│   │   ├── LDM-2022-10-05.md
│   │   ├── LDM-2022-10-10.md
│   │   ├── LDM-2022-10-12.md
│   │   ├── LDM-2022-10-17.md
│   │   ├── LDM-2022-10-19.md
│   │   ├── LDM-2022-10-26.md
│   │   ├── LDM-2022-11-02.md
│   │   ├── LDM-2022-11-30.md
│   │   ├── LDM-2022-12-14.md
│   │   └── README.md
│   ├── 2023/
│   │   ├── LDM-2023-01-09.md
│   │   ├── LDM-2023-01-11.md
│   │   ├── LDM-2023-01-18.md
│   │   ├── LDM-2023-02-01.md
│   │   ├── LDM-2023-02-15.md
│   │   ├── LDM-2023-02-22.md
│   │   ├── LDM-2023-02-27.md
│   │   ├── LDM-2023-03-01.md
│   │   ├── LDM-2023-03-08.md
│   │   ├── LDM-2023-03-13.md
│   │   ├── LDM-2023-04-03.md
│   │   ├── LDM-2023-04-10.md
│   │   ├── LDM-2023-04-26.md
│   │   ├── LDM-2023-05-01.md
│   │   ├── LDM-2023-05-03.md
│   │   ├── LDM-2023-05-08.md
│   │   ├── LDM-2023-05-15.md
│   │   ├── LDM-2023-05-17.md
│   │   ├── LDM-2023-05-31.md
│   │   ├── LDM-2023-06-05.md
│   │   ├── LDM-2023-06-19.md
│   │   ├── LDM-2023-07-12.md
│   │   ├── LDM-2023-07-17.md
│   │   ├── LDM-2023-07-24.md
│   │   ├── LDM-2023-07-26.md
│   │   ├── LDM-2023-07-31.md
│   │   ├── LDM-2023-08-07.md
│   │   ├── LDM-2023-08-09.md
│   │   ├── LDM-2023-08-14.md
│   │   ├── LDM-2023-08-16.md
│   │   ├── LDM-2023-09-18.md
│   │   ├── LDM-2023-09-20.md
│   │   ├── LDM-2023-09-25.md
│   │   ├── LDM-2023-09-27.md
│   │   ├── LDM-2023-10-02.md
│   │   ├── LDM-2023-10-04.md
│   │   ├── LDM-2023-10-09.md
│   │   ├── LDM-2023-10-11-specification-update.md
│   │   ├── LDM-2023-10-11.md
│   │   ├── LDM-2023-10-16.md
│   │   ├── LDM-2023-11-15.md
│   │   ├── LDM-2023-11-27.md
│   │   ├── LDM-2023-12-04.md
│   │   ├── LDM-2023-12-11.md
│   │   └── README.md
│   ├── 2024/
│   │   ├── LDM-2024-01-08.md
│   │   ├── LDM-2024-01-10.md
│   │   ├── LDM-2024-01-22.md
│   │   ├── LDM-2024-01-29.md
│   │   ├── LDM-2024-01-31.md
│   │   ├── LDM-2024-02-05.md
│   │   ├── LDM-2024-02-07.md
│   │   ├── LDM-2024-02-21.md
│   │   ├── LDM-2024-02-26.md
│   │   ├── LDM-2024-02-28.md
│   │   ├── LDM-2024-03-04.md
│   │   ├── LDM-2024-03-11.md
│   │   ├── LDM-2024-03-27.md
│   │   ├── LDM-2024-04-01.md
│   │   ├── LDM-2024-04-08.md
│   │   ├── LDM-2024-04-15.md
│   │   ├── LDM-2024-04-17.md
│   │   ├── LDM-2024-04-22.md
│   │   ├── LDM-2024-04-24.md
│   │   ├── LDM-2024-05-01.md
│   │   ├── LDM-2024-05-08.md
│   │   ├── LDM-2024-05-13.md
│   │   ├── LDM-2024-05-15-KeyValuePairCorrespondence.md
│   │   ├── LDM-2024-05-15.md
│   │   ├── LDM-2024-06-03.md
│   │   ├── LDM-2024-06-10.md
│   │   ├── LDM-2024-06-12.md
│   │   ├── LDM-2024-06-17.md
│   │   ├── LDM-2024-06-24.md
│   │   ├── LDM-2024-06-26.md
│   │   ├── LDM-2024-07-15-usage-data.md
│   │   ├── LDM-2024-07-15.md
│   │   ├── LDM-2024-07-17.md
│   │   ├── LDM-2024-07-22-ref-struct-interface-examples.md
│   │   ├── LDM-2024-07-22.md
│   │   ├── LDM-2024-07-24.md
│   │   ├── LDM-2024-08-14.md
│   │   ├── LDM-2024-08-19.md
│   │   ├── LDM-2024-08-21.md
│   │   ├── LDM-2024-08-26.md
│   │   ├── LDM-2024-08-28.md
│   │   ├── LDM-2024-09-04.md
│   │   ├── LDM-2024-09-11.md
│   │   ├── LDM-2024-09-18.md
│   │   ├── LDM-2024-09-30.md
│   │   ├── LDM-2024-10-02.md
│   │   ├── LDM-2024-10-07-extension-compat.md
│   │   ├── LDM-2024-10-07.md
│   │   ├── LDM-2024-10-09.md
│   │   ├── LDM-2024-10-14-Enumerable-extension.cs
│   │   ├── LDM-2024-10-14-Enumerable-extensions.cs
│   │   ├── LDM-2024-10-14.md
│   │   ├── LDM-2024-10-16.md
│   │   ├── LDM-2024-10-28.md
│   │   ├── LDM-2024-10-30.md
│   │   ├── LDM-2024-11-04-patterns.md
│   │   ├── LDM-2024-11-04.md
│   │   ├── LDM-2024-11-13.md
│   │   ├── LDM-2024-11-20.md
│   │   ├── LDM-2024-12-04.md
│   │   ├── LDM-2024-12-09.md
│   │   └── README.md
│   ├── 2025/
│   │   ├── LDM-2025-01-06.md
│   │   ├── LDM-2025-01-13.md
│   │   ├── LDM-2025-01-15.md
│   │   ├── LDM-2025-01-22.md
│   │   ├── LDM-2025-02-12.md
│   │   ├── LDM-2025-02-19.md
│   │   ├── LDM-2025-02-24.md
│   │   ├── LDM-2025-02-26.md
│   │   ├── LDM-2025-03-03.md
│   │   ├── LDM-2025-03-05.md
│   │   ├── LDM-2025-03-10.md
│   │   ├── LDM-2025-03-12.md
│   │   ├── LDM-2025-03-17.md
│   │   ├── LDM-2025-03-19.md
│   │   ├── LDM-2025-03-24.md
│   │   ├── LDM-2025-04-02.md
│   │   ├── LDM-2025-04-07.md
│   │   ├── LDM-2025-04-09.md
│   │   ├── LDM-2025-04-14.md
│   │   ├── LDM-2025-04-16.md
│   │   ├── LDM-2025-04-23.md
│   │   ├── LDM-2025-05-05.md
│   │   ├── LDM-2025-05-07.md
│   │   ├── LDM-2025-05-12.md
│   │   ├── LDM-2025-05-28.md
│   │   ├── LDM-2025-06-04.md
│   │   ├── LDM-2025-06-09.md
│   │   ├── LDM-2025-06-11.md
│   │   ├── LDM-2025-06-18.md
│   │   ├── LDM-2025-06-23.md
│   │   ├── LDM-2025-06-25.md
│   │   ├── LDM-2025-06-30.md
│   │   ├── LDM-2025-07-30.md
│   │   ├── LDM-2025-08-13.md
│   │   ├── LDM-2025-08-18.md
│   │   ├── LDM-2025-08-20.md
│   │   ├── LDM-2025-08-27.md
│   │   ├── LDM-2025-09-10.md
│   │   ├── LDM-2025-09-17.md
│   │   ├── LDM-2025-09-24.md
│   │   ├── LDM-2025-09-29.md
│   │   ├── LDM-2025-10-01.md
│   │   ├── LDM-2025-10-13.md
│   │   ├── LDM-2025-10-29.md
│   │   ├── LDM-2025-11-05.md
│   │   ├── LDM-2025-11-12.md
│   │   ├── LDM-2025-12-10.md
│   │   ├── LDM-2025-12-17.md
│   │   └── README.md
│   ├── 2026/
│   │   ├── LDM-2026-01-12.md
│   │   ├── LDM-2026-01-21.md
│   │   ├── LDM-2026-01-26.md
│   │   ├── LDM-2026-02-02.md
│   │   ├── LDM-2026-02-04.md
│   │   ├── LDM-2026-02-09.md
│   │   ├── LDM-2026-02-11.md
│   │   ├── LDM-2026-03-09.md
│   │   └── README.md
│   ├── README.md
│   └── working-groups/
│       ├── collection-literals/
│       │   ├── CL-2022-10-06.md
│       │   ├── CL-2022-10-14.md
│       │   ├── CL-2022-10-21.md
│       │   ├── CL-2023-04-05.md
│       │   ├── CL-2023-04-28.md
│       │   ├── CL-2023-05-10.md
│       │   ├── CL-2023-05-26.md
│       │   ├── CL-2023-06-12.md
│       │   ├── CL-2023-06-26.md
│       │   ├── CL-2023-07-26.md
│       │   ├── CL-2023-08-03.md
│       │   ├── CL-2023-08-10.md
│       │   ├── CL-2023-08-11.md
│       │   ├── CL-2024-01-23.md
│       │   ├── CL-LDM-2023-05-31.md
│       │   ├── CL-LDM-2023-08-14.md
│       │   ├── Compiler-synthesized-types.md
│       │   ├── Core-interface-target-type-proposal.md
│       │   ├── LDM-questions-2023-08-15.md
│       │   ├── collection-expressions-inferred-type.md
│       │   └── collection-expressions-next.md
│       ├── discriminated-unions/
│       │   ├── Case Classes.md
│       │   ├── Closed Enums.md
│       │   ├── Closed Hierarchies.md
│       │   ├── DU-2022-10-19.md
│       │   ├── DU-2022-10-24.md
│       │   ├── DU-2022-10-31.md
│       │   ├── DU-2022-11-07.md
│       │   ├── Nominal Type Unions.md
│       │   ├── Runtime Type Unions.md
│       │   ├── Trade Off Matrix.md
│       │   ├── TypeUnions.md
│       │   ├── Union implementation challenges.md
│       │   ├── allows.md
│       │   ├── brace-syntax.md
│       │   ├── enum-like-unions.md
│       │   ├── extended-enums.md
│       │   ├── original-nominal-type-unions.md
│       │   ├── pre-unification-proposals/
│       │   │   ├── custom-unions.md
│       │   │   ├── nominal-type-unions.md
│       │   │   ├── non-boxing-access-pattern.md
│       │   │   └── union-interfaces.md
│       │   ├── to-nest-or-not-to-nest.md
│       │   ├── type-value-conversion.md
│       │   ├── union-patterns-update.md
│       │   └── union-proposals-overview.md
│       ├── expressions-statements/
│       │   └── ES-2022-11-30.md
│       ├── extensions/
│       │   ├── Compatibility through coexistence between extension types and extension methods.md
│       │   ├── Extension-API-docs.md
│       │   ├── anonymous-extension-declarations.md
│       │   ├── compat-mode-in-extensions.md
│       │   ├── compromise-design-for-extensions.md
│       │   ├── content-based-naming.md
│       │   ├── disambiguation-syntax-examples.md
│       │   ├── extending-extensions-a-guide-to-relaxation.md
│       │   ├── extension-member-disambiguation.md
│       │   ├── extension-members-unified-proposal.md
│       │   ├── extensions-an-evolution-of-extension-methods.md
│       │   ├── extensions-as-static-types.md
│       │   ├── extensions-lookup.md
│       │   ├── extensions_v2.md
│       │   ├── implicit-compatibility-for-ported-extension-methods.md
│       │   ├── metadata-names.md
│       │   ├── rename-to-roles-and-extensions.md
│       │   └── the-design-space-for-extensions.md
│       ├── field-keyword/
│       │   ├── FK-2024-06-26.md
│       │   ├── FK-2024-08-07 Nullability analysis with the `field` keyword.md
│       │   └── FK-2024-08-07.md
│       ├── interceptors/
│       │   ├── IC-2023-03-20.md
│       │   ├── IC-2023-04-04.md
│       │   └── interceptors-issues-2024-01.md
│       ├── nullability-improvements/
│       │   ├── NI-2022-10-24.md
│       │   ├── NI-2022-11-01.md
│       │   ├── NI-2022-11-07.md
│       │   └── NI-2022-11-22.md
│       ├── params-improvements/
│       │   ├── PI-2022-10-25.md
│       │   └── PI-2022-11-03.md
│       ├── ref-improvements/
│       │   ├── REF-2022-11-11.md
│       │   └── ignore-overloads-in-expressions.md
│       ├── roles/
│       │   ├── extension-wg-2024-06-07.md
│       │   ├── extension-wg-2024-06-14.md
│       │   ├── extension-wg-2024-06-21.md
│       │   ├── extensions-2023-02-21.md
│       │   ├── extensions-wg-2023-04-27.md
│       │   ├── extensions-wg-2023-06-07.md
│       │   ├── extensions-wg-2024-03-05.md
│       │   ├── extensions-wg-2024-08-09.md
│       │   ├── roles-2022-11-10.md
│       │   ├── roles-2023-01-23.md
│       │   ├── roles-2023-01-25.md
│       │   └── roles-2023-02-15.md
│       └── unsafe-evolution/
│           └── unsafe-alternative-syntax.md
├── proposals/
│   ├── README.md
│   ├── anonymous-using-declarations.md
│   ├── async-main-update.md
│   ├── block-bodied-switch-expression-arms.md
│   ├── breaking-change-warnings.md
│   ├── case-declarations.md
│   ├── closed-enums.md
│   ├── closed-hierarchies.md
│   ├── collection-expression-arguments.md
│   ├── compound-assignment-in-initializer-and-with.md
│   ├── conditional-operator-access-syntax-refinement.md
│   ├── csharp-10.0/
│   │   ├── GlobalUsingDirective.md
│   │   ├── async-method-builders.md
│   │   ├── caller-argument-expression.md
│   │   ├── constant_interpolated_strings.md
│   │   ├── enhanced-line-directives.md
│   │   ├── extended-property-patterns.md
│   │   ├── file-scoped-namespaces.md
│   │   ├── improved-definite-assignment.md
│   │   ├── improved-interpolated-strings.md
│   │   ├── lambda-improvements.md
│   │   ├── parameterless-struct-constructors.md
│   │   └── record-structs.md
│   ├── csharp-11.0/
│   │   ├── auto-default-structs.md
│   │   ├── checked-user-defined-operators.md
│   │   ├── extended-nameof-scope.md
│   │   ├── file-local-types.md
│   │   ├── generic-attributes.md
│   │   ├── list-patterns.md
│   │   ├── low-level-struct-improvements.md
│   │   ├── new-line-in-interpolation.md
│   │   ├── numeric-intptr.md
│   │   ├── pattern-match-span-of-char-on-string.md
│   │   ├── raw-string-literal.md
│   │   ├── relaxing_shift_operator_requirements.md
│   │   ├── required-members.md
│   │   ├── static-abstracts-in-interfaces.md
│   │   ├── unsigned-right-shift-operator.md
│   │   └── utf8-string-literals.md
│   ├── csharp-12.0/
│   │   ├── collection-expressions.md
│   │   ├── experimental-attribute.md
│   │   ├── inline-arrays.md
│   │   ├── lambda-method-group-defaults.md
│   │   ├── primary-constructors.md
│   │   ├── ref-readonly-parameters.md
│   │   └── using-alias-types.md
│   ├── csharp-13.0/
│   │   ├── collection-expressions-better-conversion.md
│   │   ├── esc-escape-sequence.md
│   │   ├── lock-object.md
│   │   ├── method-group-natural-type-improvements.md
│   │   ├── overload-resolution-priority.md
│   │   ├── params-collections.md
│   │   ├── partial-properties.md
│   │   ├── ref-struct-interfaces.md
│   │   └── ref-unsafe-in-iterators-async.md
│   ├── csharp-14.0/
│   │   ├── extension-operators.md
│   │   ├── extensions.md
│   │   ├── field-keyword.md
│   │   ├── first-class-span-types.md
│   │   ├── ignored-directives.md
│   │   ├── null-conditional-assignment.md
│   │   ├── optional-and-named-parameters-in-expression-trees.md
│   │   ├── partial-events-and-constructors.md
│   │   ├── simple-lambda-parameters-with-modifiers.md
│   │   ├── unbound-generic-types-in-nameof.md
│   │   └── user-defined-compound-assignment.md
│   ├── csharp-6.0/
│   │   ├── empty-params-array.md
│   │   ├── enum-base-type.md
│   │   └── struct-autoprop-init.md
│   ├── csharp-7.0/
│   │   ├── binary-literals.md
│   │   ├── digit-separators.md
│   │   ├── expression-bodied-everything.md
│   │   ├── local-functions.md
│   │   ├── out-var.md
│   │   ├── pattern-matching.md
│   │   ├── ref-locals-returns.md
│   │   ├── task-types.md
│   │   ├── throw-expression.md
│   │   └── tuples.md
│   ├── csharp-7.1/
│   │   ├── README.md
│   │   ├── async-main.md
│   │   ├── generics-pattern-match.md
│   │   ├── infer-tuple-names.md
│   │   └── target-typed-default.md
│   ├── csharp-7.2/
│   │   ├── conditional-ref.md
│   │   ├── leading-separator.md
│   │   ├── non-trailing-named-arguments.md
│   │   ├── private-protected.md
│   │   ├── readonly-ref.md
│   │   ├── readonly-struct.md
│   │   ├── ref-extension-methods.md
│   │   ├── ref-struct-and-span.md
│   │   └── span-safety.md
│   ├── csharp-7.3/
│   │   ├── auto-prop-field-attrs.md
│   │   ├── blittable.md
│   │   ├── enum-delegate-constraints.md
│   │   ├── expression-variables-in-initializers.md
│   │   ├── improved-overload-candidates.md
│   │   ├── indexing-movable-fixed-fields.md
│   │   ├── pattern-based-fixed.md
│   │   ├── ref-local-reassignment.md
│   │   ├── ref-loops.md
│   │   ├── stackalloc-array-initializers.md
│   │   └── tuple-equality.md
│   ├── csharp-8.0/
│   │   ├── README.md
│   │   ├── alternative-interpolated-verbatim.md
│   │   ├── async-streams.md
│   │   ├── async-using.md
│   │   ├── constraints-in-overrides.md
│   │   ├── constructed-unmanaged.md
│   │   ├── default-interface-methods.md
│   │   ├── nested-stackalloc.md
│   │   ├── notnull-constraint.md
│   │   ├── null-coalescing-assignment.md
│   │   ├── nullable-reference-types-specification.md
│   │   ├── nullable-reference-types.md
│   │   ├── obsolete-accessor.md
│   │   ├── patterns.md
│   │   ├── ranges.cs
│   │   ├── ranges.md
│   │   ├── readonly-instance-members.md
│   │   ├── shadowing-in-nested-functions.md
│   │   ├── static-local-functions.md
│   │   ├── unconstrained-null-coalescing.md
│   │   └── using.md
│   ├── csharp-9.0/
│   │   ├── covariant-returns.md
│   │   ├── extending-partial-methods.md
│   │   ├── extension-getenumerator.md
│   │   ├── function-pointers.md
│   │   ├── init.md
│   │   ├── lambda-discard-parameters.md
│   │   ├── local-function-attributes.md
│   │   ├── module-initializers.md
│   │   ├── native-integers.md
│   │   ├── nullable-constructor-analysis.md
│   │   ├── nullable-parameter-default-value-analysis.md
│   │   ├── nullable-reference-types-specification.md
│   │   ├── patterns3.md
│   │   ├── records.md
│   │   ├── skip-localsinit.md
│   │   ├── static-anonymous-functions.md
│   │   ├── target-typed-conditional-expression.md
│   │   ├── target-typed-new.md
│   │   ├── top-level-statements.md
│   │   ├── unconstrained-type-parameter-annotations.md
│   │   └── variance-safety-for-static-interface-members.md
│   ├── deconstruction-in-lambda-parameters.md
│   ├── dictionary-expressions.md
│   ├── enhanced-switch-statements.md
│   ├── expand-ref.md
│   ├── extension-indexers.md
│   ├── fieldof.md
│   ├── final-initializers.md
│   ├── immediately-enumerated-collection-expressions.md
│   ├── inactive/
│   │   ├── README.md
│   │   ├── list-patterns-enumerables.md
│   │   ├── pointer-null-coalescing.md
│   │   └── repeated-attributes.md
│   ├── inference-for-constructor-calls.md
│   ├── inference-for-type-patterns.md
│   ├── interpolated-string-handler-argument-value.md
│   ├── iterators-in-lambdas.md
│   ├── labeled-break-continue.md
│   ├── left-right-join-in-query-expressions.md
│   ├── multiple-using-var-discards.md
│   ├── null-conditional-await.md
│   ├── pattern-variables.md
│   ├── proposal-template.md
│   ├── readonly-parameters.md
│   ├── readonly-setter-calls-on-non-variables.md
│   ├── rejected/
│   │   ├── README.md
│   │   ├── collection-expressions-in-foreach.md
│   │   ├── declaration-expressions.md
│   │   ├── discriminated-unions.md
│   │   ├── fixed-sized-buffers.md
│   │   ├── format.md
│   │   ├── interpolated-string-handler-method-names.md
│   │   ├── intptr-operators.md
│   │   ├── intrinsics.md
│   │   ├── nullable-enhanced-common-type.md
│   │   ├── param-nullchecking.md
│   │   ├── params-span.md
│   │   ├── readonly-locals.md
│   │   ├── records.md
│   │   ├── recordsv2.md
│   │   ├── self-constraint.md
│   │   └── static-delegates.md
│   ├── relaxed-partial-ref-ordering.md
│   ├── speclet-disclaimer.md
│   ├── standard-unions.md
│   ├── target-typed-generic-type-inference.md
│   ├── target-typed-static-member-access.md
│   ├── top-level-members.md
│   ├── type-parameter-inference-from-constraints.md
│   ├── unions.md
│   ├── unsafe-evolution.md
│   └── unsigned-sizeof.md
└── spec/
    ├── LICENSE.md
    ├── README.md
    ├── arrays.md
    ├── attributes.md
    ├── basic-concepts.md
    ├── classes.md
    ├── conversions.md
    ├── delegates.md
    ├── documentation-comments.md
    ├── enums.md
    ├── exceptions.md
    ├── expressions.md
    ├── interfaces.md
    ├── introduction.md
    ├── lexical-structure.md
    ├── namespaces.md
    ├── statements.md
    ├── structs.md
    ├── types.md
    ├── unsafe-code.md
    └── variables.md
Download .txt
SYMBOL INDEX (19 symbols across 1 files)

FILE: proposals/csharp-8.0/ranges.cs
  type Index (line 3) | public readonly struct Index
    method Index (line 10) | public Index(int value, bool fromEnd)
  type Range (line 21) | public readonly struct Range
    method Range (line 26) | private Range(Index start, Index end)
    method Create (line 32) | public static Range Create(Index start, Index end) => new Range(start,...
    method FromStart (line 33) | public static Range FromStart(Index start) => new Range(start, new Ind...
    method ToEnd (line 34) | public static Range ToEnd(Index end) => new Range(new Index(0, fromEnd...
    method All (line 35) | public static Range All() => new Range(new Index(0, fromEnd: false), n...
  class Extensions (line 38) | static class Extensions
    method get_IndexerExtension (line 40) | public static int get_IndexerExtension(this int[] array, Index index) =>
    method get_IndexerExtension (line 43) | public static int get_IndexerExtension(this Span<int> span, Index inde...
    method get_IndexerExtension (line 46) | public static char get_IndexerExtension(this string s, Index index) =>
    method get_IndexerExtension (line 49) | public static Span<int> get_IndexerExtension(this int[] array, Range r...
    method get_IndexerExtension (line 52) | public static Span<int> get_IndexerExtension(this Span<int> span, Rang...
    method get_IndexerExtension (line 55) | public static string get_IndexerExtension(this string s, Range range) =>
    method Slice (line 58) | public static Span<T> Slice<T>(this T[] array, Range range)
    method Slice (line 61) | public static Span<T> Slice<T>(this Span<T> span, Range range)
    method Substring (line 67) | public static string Substring(this string s, Range range)
    method GetStartAndLength (line 73) | private static (int start, int length) GetStartAndLength(Range range, ...
Condensed preview — 863 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (6,424K chars).
[
  {
    "path": ".gitattributes",
    "chars": 12,
    "preview": "* text=auto\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 32,
    "preview": "*       @dotnet/roslyn-compiler\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 237,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Propose a language idea or ask a question\n    url: https://github.c"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/docs-feedback.yml",
    "chars": 1432,
    "preview": "name: Learn feedback control.\ndescription: |\n  ⛔ This template is hooked into the feedback control on the bottom of ever"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/proposal_template.md",
    "chars": 1299,
    "preview": "---\nname: Create a language specification\nabout: For proposals that have been invited by a team member.\ntitle: \"[Proposa"
  },
  {
    "path": ".gitignore",
    "chars": 43,
    "preview": ".vscode/*\n\n# Ignore temporary files\n~$*\n*~\n"
  },
  {
    "path": "CODE-OF-CONDUCT.md",
    "chars": 259,
    "preview": "# Code of Conduct\n\nThis project has adopted the code of conduct defined by the Contributor Covenant\nto clarify expected "
  },
  {
    "path": "Communities.md",
    "chars": 1922,
    "preview": "**Disclaimer**: This document is maintained by the C# community and not the responsibility of the C# Language Design Tea"
  },
  {
    "path": "Design-Process.md",
    "chars": 19720,
    "preview": "# Language Design Process\n\nThe language design process is the steps that a proposal takes throughout its life, going fro"
  },
  {
    "path": "Language-Version-History.md",
    "chars": 32650,
    "preview": "Features Added in C# Language Versions\n====================\n\n# C# 14.0 - .NET 10 and Visual Studio 2026 version 18.0\n- ["
  },
  {
    "path": "README.md",
    "chars": 7826,
    "preview": "# C# Language Design\n\n[![Join the chat at https://gitter.im/dotnet/csharplang](https://badges.gitter.im/dotnet/csharplan"
  },
  {
    "path": "meetings/2013/LDM-2013-10-07.md",
    "chars": 12364,
    "preview": "# C# Language Design Notes for Oct 7, 2013\n\n## Agenda\nWe looked at a couple of feature ideas that either came up recentl"
  },
  {
    "path": "meetings/2013/LDM-2013-10-21.md",
    "chars": 10997,
    "preview": "# C# Design Notes for Oct 21, 2013\n## Agenda\nPrimary constructors is the first C# 6.0 feature to be spec’ed and implemen"
  },
  {
    "path": "meetings/2013/LDM-2013-11-04.md",
    "chars": 7025,
    "preview": "# C# Design Notes for Nov 4, 2013\n## Agenda\nNext up for implementation are the features for auto-properties and function"
  },
  {
    "path": "meetings/2013/LDM-2013-12-16.md",
    "chars": 6860,
    "preview": "# C# Design Notes for Dec 16, 2013\n\n## Agenda\nThis being the last design meeting of the year, we focused on firming up s"
  },
  {
    "path": "meetings/2013/README.md",
    "chars": 1087,
    "preview": "# C# Language Design Notes for 2013\n\nOverview of meetings and agendas for 2013\n\n## Oct 7, 2013\n\n[C# Language Design Note"
  },
  {
    "path": "meetings/2014/LDM-2014-01-06.md",
    "chars": 4320,
    "preview": "# C# Design Notes for Jan 6, 2014\n\nNotes are archived [here](https://roslyn.codeplex.com/wikipage?title=CSharp%20Languag"
  },
  {
    "path": "meetings/2014/LDM-2014-02-03.md",
    "chars": 7065,
    "preview": "# C# Language Design Notes for Feb 3, 2014\n\n## Agenda\nWe iterated on some of the features currently under implementation"
  },
  {
    "path": "meetings/2014/LDM-2014-02-10.md",
    "chars": 6050,
    "preview": "# C# Design Notes for Feb 10, 2014\n\n## Agenda\n1.\tDesign of using static <_design adopted_>\n2.\tInitializers in structs <_"
  },
  {
    "path": "meetings/2014/LDM-2014-04-21.md",
    "chars": 19892,
    "preview": "# C# Language Design Notes for Apr 21, 2014\n\n## Agenda\nIn this design meeting we looked at some of the most persistent f"
  },
  {
    "path": "meetings/2014/LDM-2014-05-07.md",
    "chars": 6407,
    "preview": "# C# Language Design Notes for May 7, 2014\n\n## Agenda\n1.\tprotected and internal <_feature cut – not worth the confusion_"
  },
  {
    "path": "meetings/2014/LDM-2014-05-21.md",
    "chars": 10549,
    "preview": "# C# Language Design Notes for May 21, 2014\n\n## Agenda\n1.\tLimit the nameof feature? <_keep current design_>\n2.\tExtend pa"
  },
  {
    "path": "meetings/2014/LDM-2014-07-09.md",
    "chars": 4647,
    "preview": "# C# Language Design Notes for July 9, 2014\n\n## Agenda\n1.\tDetailed design of nameof <_details settled_>\n2.\tDesign of #pr"
  },
  {
    "path": "meetings/2014/LDM-2014-08-27.md",
    "chars": 14482,
    "preview": "# C# Design Notes for Aug 27, 2014\n\n## Agenda\nThe meeting focused on rounding out the feature set around structs.\n1.\tAll"
  },
  {
    "path": "meetings/2014/LDM-2014-09-03.md",
    "chars": 9058,
    "preview": "# C# Design Notes for Sep 3, 2014\n\nQuote of the day: “It’s a design smell. But it’s a good smell.”\n\n## Agenda\nThe meetin"
  },
  {
    "path": "meetings/2014/LDM-2014-10-01.md",
    "chars": 12323,
    "preview": "There were two agenda items...\n1. Assignment to readonly autoprops in constructors (we fleshed out details)\n2. A new com"
  },
  {
    "path": "meetings/2014/LDM-2014-10-15.md",
    "chars": 33485,
    "preview": "# nameof operator: spec v5\nThe nameof(.) operator has the form nameof(expression). The expression must have a name, and "
  },
  {
    "path": "meetings/2014/README.md",
    "chars": 3423,
    "preview": "# C# Language Design Notes for 2014\n\nOverview of meetings and agendas for 2014\n\n## Jan 6, 2014\n\n[C# Language Design Note"
  },
  {
    "path": "meetings/2015/LDM-2015-01-21.md",
    "chars": 26020,
    "preview": "C# Design Meeting Notes for Jan 21, 2015\n========================================\n\nDiscussion thread on these notes can "
  },
  {
    "path": "meetings/2015/LDM-2015-01-28.md",
    "chars": 14778,
    "preview": "C# Design Meeting Notes for Jan 28, 2015\n========================================\n\nDiscussion thread for these notes can"
  },
  {
    "path": "meetings/2015/LDM-2015-02-04.md",
    "chars": 12708,
    "preview": "C# Design Meeting Notes for Feb 4, 2015\n========================================\n\nDiscussion thread on these notes can b"
  },
  {
    "path": "meetings/2015/LDM-2015-02-11.md",
    "chars": 13501,
    "preview": "C# Design Meeting Notes for Feb 11, 2015\n=========================================\n\nDiscussion on these notes can be fou"
  },
  {
    "path": "meetings/2015/LDM-2015-03-04.md",
    "chars": 8939,
    "preview": "C# Design Meeting Notes for Mar 4, 2015\n========================================\n\nDiscussion on these notes can be found"
  },
  {
    "path": "meetings/2015/LDM-2015-03-10-17.md",
    "chars": 9990,
    "preview": "C# Design Meeting Notes for Mar 10 and 17, 2015\n===============================================\n\nDiscussion thread for t"
  },
  {
    "path": "meetings/2015/LDM-2015-03-18.md",
    "chars": 10778,
    "preview": "C# Design Meeting Notes for Mar 18, 2015\n========================================\n\nDiscussion thread for these notes can"
  },
  {
    "path": "meetings/2015/LDM-2015-03-24.md",
    "chars": 6066,
    "preview": "C# Design Meeting Notes for Mar 24, 2015\n========================================\n\nDiscussion thread on these notes is a"
  },
  {
    "path": "meetings/2015/LDM-2015-03-25-Design-Review.md",
    "chars": 7807,
    "preview": "C# Language Design Review, Mar 25, 2015\n=======================================\n\nDiscussion thread for these notes can b"
  },
  {
    "path": "meetings/2015/LDM-2015-03-25-Notes.md",
    "chars": 3326,
    "preview": "C# Design Meeting 2015-03-25\n============================\n\nDiscussion thread for these notes can be found at https://git"
  },
  {
    "path": "meetings/2015/LDM-2015-04-01-08.md",
    "chars": 6156,
    "preview": "C# Design Meeting Notes for Apr 1 and Apr 8, 2015\n=================================================\n\nDiscussion thread f"
  },
  {
    "path": "meetings/2015/LDM-2015-04-14.md",
    "chars": 6116,
    "preview": "C# Design Meeting Notes for Apr 14, 2015\n========================================\n\nDiscussion thread for these notes can"
  },
  {
    "path": "meetings/2015/LDM-2015-04-15.md",
    "chars": 4043,
    "preview": "C# Design Meeting Notes for Apr 15, 2015\n========================================\n\nDiscussion thread for these notes is "
  },
  {
    "path": "meetings/2015/LDM-2015-04-22-Design-Review.md",
    "chars": 4569,
    "preview": "# C# Language Design Review, Apr 22, 2015\n\nDiscussion for these notes can be found at https://github.com/dotnet/roslyn/i"
  },
  {
    "path": "meetings/2015/LDM-2015-05-20.md",
    "chars": 11869,
    "preview": "C# Design Meeting Notes for May 20, 2015\n========================================\n\nDiscussion for this issue can be foun"
  },
  {
    "path": "meetings/2015/LDM-2015-05-25.md",
    "chars": 2306,
    "preview": "# C# Design Meeting Notes for May 25, 2015\n\nDiscussion for these notes can be found in https://github.com/dotnet/roslyn/"
  },
  {
    "path": "meetings/2015/LDM-2015-07-01.md",
    "chars": 7228,
    "preview": "# C# Design Meeting Notes for Jul 1, 2015\n\nDiscussion for these notes can be found at https://github.com/dotnet/roslyn/i"
  },
  {
    "path": "meetings/2015/LDM-2015-07-07.md",
    "chars": 3635,
    "preview": "# C# Design Notes for Jul 7 2015\n\nDiscussion for these notes can be found at https://github.com/dotnet/roslyn/issues/503"
  },
  {
    "path": "meetings/2015/LDM-2015-08-18.md",
    "chars": 3255,
    "preview": "# C# Design Notes for Aug 18, 2015\n\nDiscussion for these notes can be found at https://github.com/dotnet/roslyn/issues/5"
  },
  {
    "path": "meetings/2015/LDM-2015-09-01.md",
    "chars": 8305,
    "preview": "C# Design Meeting Sep 1 2015\n============================\n\nDiscussion for these notes can be found at https://github.com"
  },
  {
    "path": "meetings/2015/LDM-2015-09-02.md",
    "chars": 4118,
    "preview": "C# Design Notes Sep 2 2015\n==========================\n\nDiscussion for these notes can be found at https://github.com/dot"
  },
  {
    "path": "meetings/2015/LDM-2015-09-08.md",
    "chars": 13485,
    "preview": "# C# Design Notes for Sep 8, 2015\n\nDiscussion for these notes can be found at https://github.com/dotnet/roslyn/issues/53"
  },
  {
    "path": "meetings/2015/LDM-2015-10-07-Design-Review.md",
    "chars": 4797,
    "preview": "Notes on Records and Pattern Matching for 2015-10-07 design review\n====================================================="
  },
  {
    "path": "meetings/2015/LDM-2015-11-02-Design-Demo.md",
    "chars": 9357,
    "preview": "Here’s an outline of a demo at the MVP summit on 2015-11-02\n===========================================================\n"
  },
  {
    "path": "meetings/2015/README.md",
    "chars": 8578,
    "preview": "# C# Language Design Notes for 2015\n\nOverview of meetings and agendas for 2015\n\n\n## Jan 21, 2015\n\n[C# Design Meeting Not"
  },
  {
    "path": "meetings/2016/LDM-2016-02-29.md",
    "chars": 8746,
    "preview": "C# Language Design Notes Feb 29, 2016\n=====================================\n\nDiscussion for these notes can be found at "
  },
  {
    "path": "meetings/2016/LDM-2016-04-06.md",
    "chars": 17020,
    "preview": "C# Design Notes for Apr 6, 2016\n===============================\n\nDiscussion for these design notes can be found at https"
  },
  {
    "path": "meetings/2016/LDM-2016-04-12-22.md",
    "chars": 15923,
    "preview": "# C# Design Notes for Apr 12-22, 2016\n\nThese notes summarize discussions across a series of design meetings in April on "
  },
  {
    "path": "meetings/2016/LDM-2016-05-03-04.md",
    "chars": 8457,
    "preview": "# C# Design Notes for May 3-4, 2016\n\nThis pair of meetings further explored the space around tuple syntax, pattern match"
  },
  {
    "path": "meetings/2016/LDM-2016-05-10.md",
    "chars": 6419,
    "preview": "# C# Language Design Notes for May 10, 2016\n\nIn this meeting we took a look at the possibility of adding new kinds of ex"
  },
  {
    "path": "meetings/2016/LDM-2016-07-12.md",
    "chars": 2838,
    "preview": "# C# Language Design Notes for Jul 12, 2016\n## Agenda\n\nSeveral design details pertaining to tuples and deconstruction re"
  },
  {
    "path": "meetings/2016/LDM-2016-07-13.md",
    "chars": 6632,
    "preview": "# C# Language Design Notes for Jul 13, 2016\n## Agenda\n\nWe resolved a number of questions related to tuples and deconstru"
  },
  {
    "path": "meetings/2016/LDM-2016-07-15.md",
    "chars": 5973,
    "preview": "# C# Design Language Notes for Jul 15, 2016\n## Agenda\n\nIn this meeting we took a look at what the scope rules should be "
  },
  {
    "path": "meetings/2016/LDM-2016-08-24.md",
    "chars": 3625,
    "preview": "C# Language Design Meeting, Aug 24, 2016\n========================================\n\n## Agenda\n\nAfter a meeting-free perio"
  },
  {
    "path": "meetings/2016/LDM-2016-09-06.md",
    "chars": 797,
    "preview": "# C# Language Design Notes for Sep 6, 2016\n\n## Agenda\n\n1. How do we select `Deconstruct` methods?\n\n# How do we select De"
  },
  {
    "path": "meetings/2016/LDM-2016-10-18.md",
    "chars": 2938,
    "preview": "C# Language Design Meeting Notes, Oct 18, 2016\n==============================================\n\n\n## Agenda\n\nGo over C# 7."
  },
  {
    "path": "meetings/2016/LDM-2016-10-25-26.md",
    "chars": 6406,
    "preview": "C# Language Design Notes for Oct 25 and 26, 2016\n================================================\n\nAgenda\n------\n\n- Decl"
  },
  {
    "path": "meetings/2016/LDM-2016-11-01.md",
    "chars": 4598,
    "preview": "# C# Language Design Notes for Nov 1, 2016\n\n*Raw notes - need cleaning up*\n\n## Agenda\n\n- Abstracting over memory with `S"
  },
  {
    "path": "meetings/2016/LDM-2016-11-15.md",
    "chars": 3845,
    "preview": "C# Language Design Notes, Nov 15, 2016\n======================================\n\n> *Quote of the day*: \"Bad people don't g"
  },
  {
    "path": "meetings/2016/LDM-2016-11-16.md",
    "chars": 6367,
    "preview": "C# Language Design Notes for Nov 16, 2016\n=========================================\n\nIn this meeting we looked at the pr"
  },
  {
    "path": "meetings/2016/LDM-2016-11-30.md",
    "chars": 5198,
    "preview": "C# Language Design Notes for Nov 30, 2016\n=========================================\n\n\nAgenda\n------\n\n- Scope of while co"
  },
  {
    "path": "meetings/2016/LDM-2016-12-07-14.md",
    "chars": 6733,
    "preview": "C# Language Design Notes for Dec 7 and Dec 14, 2016\n=================================================\n\nAgenda\n------\n\n- "
  },
  {
    "path": "meetings/2016/README.md",
    "chars": 3970,
    "preview": "# C# Language Design Notes for 2016\n\nOverview of meetings and agendas for 2016\n\n## Feb 29, 2016\n\n[C# Language Design Not"
  },
  {
    "path": "meetings/2017/CLR-2017-03-23.md",
    "chars": 4785,
    "preview": "2017-03-23 CLR Behavior for Default Interface Methods\n==========================================\n\nMet today with\n- [Neal"
  },
  {
    "path": "meetings/2017/LDM-2017-01-10.md",
    "chars": 1891,
    "preview": "# C# Language Design Notes for Jan 10, 2017\n\n## Agenda\n\n- Discriminated unions via \"closed\" types\n\n# Discriminated union"
  },
  {
    "path": "meetings/2017/LDM-2017-01-11.md",
    "chars": 2338,
    "preview": "# C# Language Design Notes for Jan 11, 2017\n\n*Raw notes - need cleaning up*\n\n## Agenda\n\n- Language aspects of [compiler "
  },
  {
    "path": "meetings/2017/LDM-2017-01-17.md",
    "chars": 2761,
    "preview": "# C# Language Design Notes for Jan 17, 2017\n\n## Agenda\n\nA few C# 7.0 issues to review.\n\n1. Constant pattern semantics: w"
  },
  {
    "path": "meetings/2017/LDM-2017-01-18.md",
    "chars": 7246,
    "preview": "# C# Language Design Notes for Jan 18, 2017\n\n*Raw notes - need cleaning up*\n\n## Agenda\n\n- Async streams (visit from Oren"
  },
  {
    "path": "meetings/2017/LDM-2017-02-14.md",
    "chars": 150,
    "preview": "# C# Language Design Notes for Feb 14, 2017\n\n*Upcoming meeting*\n\n## Agenda\n\n- Meet with Unity to discuss language featur"
  },
  {
    "path": "meetings/2017/LDM-2017-02-15.md",
    "chars": 91,
    "preview": "# C# Language Design Notes for Feb 15, 2017\n\n*Upcoming meeting*\n\n## Agenda\n\n- Design Review"
  },
  {
    "path": "meetings/2017/LDM-2017-02-21.md",
    "chars": 5907,
    "preview": "# C# Language Design Notes for Feb 21, 2017\n\n## Agenda\n\nWe triaged some of the [championed features](https://github.com/"
  },
  {
    "path": "meetings/2017/LDM-2017-02-22.md",
    "chars": 6215,
    "preview": "# C# Language Design Notes for Feb 22, 2017\n\n## Agenda\n\nWe went over the proposal for `ref readonly`: [Champion \"Readonl"
  },
  {
    "path": "meetings/2017/LDM-2017-02-28.md",
    "chars": 5123,
    "preview": "# C# Language Design Notes for Feb 28, 2017\n\n*Quote of the Day:* \"I don't have time to dislike your proposal, but I do!\""
  },
  {
    "path": "meetings/2017/LDM-2017-03-01.md",
    "chars": 6579,
    "preview": "# C# Language Design Notes for Mar 1, 2017\n\n## Agenda\n\n1. Shapes and extensions (*exploration*)\n2. Conditional refs (*or"
  },
  {
    "path": "meetings/2017/LDM-2017-03-07.md",
    "chars": 8792,
    "preview": "# C# Language Design Notes for Mar 7, 2017\n\nQuote of the Day: \"Now `(T)default` means the same as `default(T)`!\"\n\n## Age"
  },
  {
    "path": "meetings/2017/LDM-2017-03-08.md",
    "chars": 5071,
    "preview": "# C# Language Design Notes for Mar 8, 2017\n\n## Agenda\n\nWe looked at default interface member implementations.\n\n1. Xamari"
  },
  {
    "path": "meetings/2017/LDM-2017-03-15.md",
    "chars": 4255,
    "preview": "# C# Language Design Notes for Mar 15, 2017\n\n*Quote of the Day:* \"Little leek - isn't that called a spring onion?\"\n*Quot"
  },
  {
    "path": "meetings/2017/LDM-2017-03-21.md",
    "chars": 5749,
    "preview": "# C# Language Design Notes for Mar 21, 2017\n\n## Agenda\n\nDiscussion of default interface member implementations, based on"
  },
  {
    "path": "meetings/2017/LDM-2017-03-28.md",
    "chars": 1289,
    "preview": "# C# Language Design Notes for Mar 28, 2017\n\n## Agenda\n\nDesign some remaining 7.1 features\n\n1. Fix pattern matching rest"
  },
  {
    "path": "meetings/2017/LDM-2017-03-29.md",
    "chars": 3459,
    "preview": "# C# Language Design Notes for Mar 29, 2017\n\n## Agenda\n\n1. Nullable scenarios\n2. `Span<T>` safety\n\n# Nullable scenarios\n"
  },
  {
    "path": "meetings/2017/LDM-2017-04-05.md",
    "chars": 5608,
    "preview": "# C# Language Design Notes for Apr 5, 2017\n\n## Agenda\n\n1. Non-virtual members in interfaces\n2. Inferred tuple element na"
  },
  {
    "path": "meetings/2017/LDM-2017-04-11.md",
    "chars": 2284,
    "preview": "# C# Language Design Notes for Apr 11, 2017\n\n## Agenda\n\n1. Runtime behavior of ambiguous default implementation\n\n\n# Runt"
  },
  {
    "path": "meetings/2017/LDM-2017-04-18.md",
    "chars": 5346,
    "preview": "# C# Language Design Notes for Apr 18, 2017\n\n*Quote of the Day*: \"I don't want to require `MainAsync`. It sounds like ma"
  },
  {
    "path": "meetings/2017/LDM-2017-04-19.md",
    "chars": 3110,
    "preview": "# C# Language Design Notes for Apr 19, 2017\n\n*Quote of the day*: \"I'm not thrilled with the decision, but it was a const"
  },
  {
    "path": "meetings/2017/LDM-2017-05-16.md",
    "chars": 2437,
    "preview": "# C# Language Design Notes for May 16, 2017\n\n## Agenda\n\n1. Triage C# 7.1 features that didn't make it\n2. Look at C# 7.2 "
  },
  {
    "path": "meetings/2017/LDM-2017-05-17.md",
    "chars": 3919,
    "preview": "# C# Language Design Notes for May 17, 2017\n\n## Agenda\n\nMore questions about default interface member implementations\n\n1"
  },
  {
    "path": "meetings/2017/LDM-2017-05-26.md",
    "chars": 3519,
    "preview": "# C# Language Design Notes for May 26, 2017\n\n## Agenda\n\n1. Native ints\n\n# Native ints\n\nWe would like to supply high-qual"
  },
  {
    "path": "meetings/2017/LDM-2017-05-31.md",
    "chars": 7454,
    "preview": "# C# Language Design Notes for May 31, 2017\n\n## Agenda\n\n1. Default interface members: overriding or implementing?\n2. Dow"
  },
  {
    "path": "meetings/2017/LDM-2017-06-13.md",
    "chars": 2771,
    "preview": "# C# Language Design Notes for Jun 13, 2017\n\n## Agenda\n\n1. Native-size ints\n2. Native-size floats\n\n\n# Native-size ints\n\n"
  },
  {
    "path": "meetings/2017/LDM-2017-06-14.md",
    "chars": 9764,
    "preview": "# C# Language Design Notes for Jun 14, 2017\n\n## Agenda\n\nSeveral issues related to default implementations of interface m"
  },
  {
    "path": "meetings/2017/LDM-2017-06-27.md",
    "chars": 5424,
    "preview": "# C# Language Design Notes for Jun 27, 2017\n\n*Quotes of the day:*\n> \"Let's support most operators, but not equal and not"
  },
  {
    "path": "meetings/2017/LDM-2017-06-28.md",
    "chars": 4794,
    "preview": "# C# Language Design Notes for Jun 28, 2017\n\n## Agenda\n1. Tuple name round-tripping between C# 6.0 and C# 7.0\n2. Deconst"
  },
  {
    "path": "meetings/2017/LDM-2017-07-05.md",
    "chars": 3282,
    "preview": "# C# Language Design Notes for Jul 5, 2017\n\n## Agenda\n\nTriage of features in the C# 7.2 milestone. They don't all fit: w"
  },
  {
    "path": "meetings/2017/LDM-2017-07-26.md",
    "chars": 6395,
    "preview": "# C# Language Design Notes for Jul 24 and 26, 2017\n\n## Agenda\n\nWe started putting a series of stakes in the ground for n"
  },
  {
    "path": "meetings/2017/LDM-2017-08-07.md",
    "chars": 10633,
    "preview": "# C# Language Design Notes for Aug 7, 2017\n\n## Agenda\n\nWe continued refining the nullable reference types feature set wi"
  },
  {
    "path": "meetings/2017/LDM-2017-08-09.md",
    "chars": 7507,
    "preview": "# C# Language Design Notes for Aug 9, 2017\n\n## Agenda\n\nWe discussed how nullable reference types should work in a number"
  },
  {
    "path": "meetings/2017/LDM-2017-08-14.md",
    "chars": 5993,
    "preview": "# C# Language Design Notes for Aug 14, 2017\n\n## Agenda\n\nWe looked at the interaction between generics and nullable refer"
  },
  {
    "path": "meetings/2017/LDM-2017-08-16.md",
    "chars": 2413,
    "preview": "# C# Language Design Notes for Aug 16, 2017\n\n*Quote of the day:*\n> \"It's an open question whether we go out with a bang`"
  },
  {
    "path": "meetings/2017/LDM-2017-08-21.md",
    "chars": 1457,
    "preview": "# C# Language Design for Aug 21, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your ow"
  },
  {
    "path": "meetings/2017/LDM-2017-08-23.md",
    "chars": 6203,
    "preview": "# C# Language Design Notes for Aug 23, 2017\n\n## Agenda\n\nWe discussed various aspects of nullable reference types\n\n1. How"
  },
  {
    "path": "meetings/2017/LDM-2017-08-28.md",
    "chars": 3133,
    "preview": "# C# Language Design Notes for Aug 28, 2017\n\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2017/LDM-2017-08-30.md",
    "chars": 3591,
    "preview": "# C# Language Design Notes for Aug 30, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/LDM-2017-09-25.md",
    "chars": 1567,
    "preview": "# C# Language Design Notes for Sep 25. 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/LDM-2017-09-27.md",
    "chars": 4330,
    "preview": "# C# Language Design Notes for Sep 27, 2017\n\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2017/LDM-2017-10-02.md",
    "chars": 2005,
    "preview": "# Milestone philosophy\n\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!***\n\n7"
  },
  {
    "path": "meetings/2017/LDM-2017-10-04.md",
    "chars": 7014,
    "preview": "# C# Language Design Review, Oct 4, 2017\n\n*Quote of the Day:* \n> \"You don't get to use this with your grandfather's Olds"
  },
  {
    "path": "meetings/2017/LDM-2017-10-09.md",
    "chars": 1790,
    "preview": "# C# Language Design Notes for Oct 9, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at yo"
  },
  {
    "path": "meetings/2017/LDM-2017-10-11.md",
    "chars": 5147,
    "preview": "# C# Language Design Notes for Oct 11, 2017\n\n## Agenda\n\nWe looked at the Oct 4 design review feedback for nullable refer"
  },
  {
    "path": "meetings/2017/LDM-2017-10-16.md",
    "chars": 2567,
    "preview": "# C# Language Design Notes for Oct 16, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/LDM-2017-10-18.md",
    "chars": 2611,
    "preview": "# C# Language Design Notes for Oct 18, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/LDM-2017-10-25.md",
    "chars": 2194,
    "preview": "# C# Language Design Notes for Oct 25, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2017/LDM-2017-11-06.md",
    "chars": 1835,
    "preview": "# C# Language Design Notes for Nov 6, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/LDM-2017-11-08.md",
    "chars": 3197,
    "preview": "# C# Language Design Notes for Nov 8, 2017\n\n## Agenda\n\nWe went over the status of the prototype for nullable reference "
  },
  {
    "path": "meetings/2017/LDM-2017-11-20.md",
    "chars": 2675,
    "preview": "# C# Language Design Notes for Nov 20, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2017/LDM-2017-11-27.md",
    "chars": 3810,
    "preview": "# C# Language Design Notes for Nov 27, 2017\n\n## Agenda\n\nWe went over the feedback on the nullable reference types proto"
  },
  {
    "path": "meetings/2017/LDM-2017-11-29.md",
    "chars": 2558,
    "preview": "# C# Language Design Notes for Nov 29, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2017/LDM-2017-12-04.md",
    "chars": 5013,
    "preview": "# C# Language Design Notes for Dec 4, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/LDM-2017-12-06.md",
    "chars": 2854,
    "preview": "# C# Language Design Notes for Dec 6, 2017\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2017/README.md",
    "chars": 10858,
    "preview": "# C# Language Design Notes for 2017\n\nOverview of meetings and agendas for 2017\n\n\n## Jan 10, 2017\n[C# Language Design Not"
  },
  {
    "path": "meetings/2018/LDM-2018-01-03.md",
    "chars": 5883,
    "preview": "# C# Language Design Notes for Jan 3, 2018\n\nQuote of the Day: \"What about `CallerPoliticalAffiliationAttribute`?\"\n\n\n## "
  },
  {
    "path": "meetings/2018/LDM-2018-01-10.md",
    "chars": 1044,
    "preview": "# C# Language Design Notes for Jan 10, 2018\n\n## Agenda\n\n1. Ranges and endpoint types\n \n\n# Ranges and endpoint types\nWou"
  },
  {
    "path": "meetings/2018/LDM-2018-01-18.md",
    "chars": 6566,
    "preview": "# C# Language Design Notes for Jan 18, 2018\n\n## Agenda\n\nWe discussed the range operator in C# and the underlying types "
  },
  {
    "path": "meetings/2018/LDM-2018-01-22.md",
    "chars": 3431,
    "preview": "# C# Language Design Notes for Jan 22, 2018\n\n## Agenda\n\nWe discussed the range operator in C# and the underlying types "
  },
  {
    "path": "meetings/2018/LDM-2018-01-24.md",
    "chars": 5878,
    "preview": "# C# Language Design Notes for Jan 24, 2018\n\n## Agenda\n\n1. Ref reassignment\n2. New constraints\n3. Target typed stackall"
  },
  {
    "path": "meetings/2018/LDM-2018-01-31.md",
    "chars": 2827,
    "preview": "# C# Language Design for Jan 31, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your o"
  },
  {
    "path": "meetings/2018/LDM-2018-02-05.md",
    "chars": 1191,
    "preview": "# C# Language Design Notes for Feb 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your"
  },
  {
    "path": "meetings/2018/LDM-2018-02-07.md",
    "chars": 2323,
    "preview": "# C# Language Design Notes for Feb 7, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2018/LDM-2018-02-14.md",
    "chars": 3776,
    "preview": "# C# Language Design Notes for Feb 14, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-02-21.md",
    "chars": 2585,
    "preview": "# C# Language Design Notes for Feb 21, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-02-26.md",
    "chars": 2900,
    "preview": "# C# Language Design Notes for Feb 26\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your o"
  },
  {
    "path": "meetings/2018/LDM-2018-02-28.md",
    "chars": 2051,
    "preview": "# C# Language Design Notes for Feb 28, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-03-14.md",
    "chars": 3938,
    "preview": "# C# Language Design Notes for Mar 14, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-03-19.md",
    "chars": 2600,
    "preview": "# C# Language Design Notes for Mar 19, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-03-21.md",
    "chars": 3078,
    "preview": "# C# Language Design Notes for Mar 21, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-03-28.md",
    "chars": 1801,
    "preview": "# C# Language Design Notes for Mar 28, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-04-02.md",
    "chars": 1825,
    "preview": "# C# Language Design Review Apr 2, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your"
  },
  {
    "path": "meetings/2018/LDM-2018-04-04.md",
    "chars": 6380,
    "preview": "# C# Language Design Notes for Apr 4, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2018/LDM-2018-04-25.md",
    "chars": 4289,
    "preview": "# C# Language Design Notes for Apr 25, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-04-30.md",
    "chars": 5115,
    "preview": "# C# Language Design Notes for Apr 30, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-05-02.md",
    "chars": 4906,
    "preview": "# C# Language Design Notes for May 2, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2018/LDM-2018-05-14.md",
    "chars": 4600,
    "preview": "# C# Language Design Notes for May 14, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-05-21.md",
    "chars": 4124,
    "preview": "# C# Language Design Notes for May 21. 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-05-23.md",
    "chars": 2629,
    "preview": "# C# Language Design Notes for May 23, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-05-30.md",
    "chars": 1896,
    "preview": "# C# Language Design Notes for May 30, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-06-04.md",
    "chars": 4117,
    "preview": "# C# Language Design Notes for Jun 4, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at y"
  },
  {
    "path": "meetings/2018/LDM-2018-06-06.md",
    "chars": 3932,
    "preview": "# C# Language Design Meeting\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!"
  },
  {
    "path": "meetings/2018/LDM-2018-06-25.md",
    "chars": 4800,
    "preview": "# C# Language Design Notes for Jun 25, 2018\n\n***Warning: These are raw notes, and still need to be cleaned up. Read at "
  },
  {
    "path": "meetings/2018/LDM-2018-07-09.md",
    "chars": 8477,
    "preview": "\nLDM July 9th, 2018\n-------------------\n\n_QOTD: \"Yeah, it's easy if you do it in a shi**y way\"_\n\n## Agenda\n\n1. `using v"
  },
  {
    "path": "meetings/2018/LDM-2018-07-11.md",
    "chars": 5804,
    "preview": "\n# C# Language Design Notes for Jul 11, 2018\n\n## Agenda\n\n1. Controlling nullable reference types with feature flags\n1. I"
  },
  {
    "path": "meetings/2018/LDM-2018-07-16.md",
    "chars": 5797,
    "preview": "# C# Language Design Notes for Jul 16, 2018\n\n## Agenda\n\n1. Null-coalescing assignment\n   1. User-defined operators\n   1"
  },
  {
    "path": "meetings/2018/LDM-2018-08-20.md",
    "chars": 5706,
    "preview": "# C# Language Design Notes for August 20, 2018\n\n## Agenda\n\nNullable open issues:\n\n1. Remaining questions on [suppression"
  },
  {
    "path": "meetings/2018/LDM-2018-08-22.md",
    "chars": 1702,
    "preview": "# C# Language Design Notes for August 22, 2018\n\n# Agenda\n\n1. Target-typed new\n1. Clarification on constraints with nulla"
  },
  {
    "path": "meetings/2018/LDM-2018-09-05.md",
    "chars": 2312,
    "preview": "# C# Language Design Notes for September 5, 2018\n\n## Agenda\n\n1. Index operator: is it a unary operator?\n1. Compiler intr"
  },
  {
    "path": "meetings/2018/LDM-2018-09-10.md",
    "chars": 4025,
    "preview": "# C# Language Design Notes for September 10, 2018\n\n## Agenda\n\n1. Nullability of constraints in inheritance and interface"
  },
  {
    "path": "meetings/2018/LDM-2018-09-19.md",
    "chars": 3783,
    "preview": "\n# C# Language Design Notes for September 19, 2018\n\n## Agenda\n\nTriage:\n\n1. XML doc comment features\n2. New `foreach` pat"
  },
  {
    "path": "meetings/2018/LDM-2018-09-24.md",
    "chars": 4187,
    "preview": "\n# C# Language Design Notes for September 24, 2018\n\n## Agenda\n\nF#/C# combined LDM\n\nTwo primary goals:\n\n1. What new C# fe"
  },
  {
    "path": "meetings/2018/LDM-2018-09-26.md",
    "chars": 3720,
    "preview": "# C# Language Design Notes for September 26, 2018\n\n## Agenda\n\nWarning waves\n\n## Discussion\n\nMotivation: Right now we con"
  },
  {
    "path": "meetings/2018/LDM-2018-10-01.md",
    "chars": 4924,
    "preview": "# C# Language Design Notes for Oct 1, 2018\n\n## Agenda\n\n1. Nullable type inference\n2. Type parameters and nullability co"
  },
  {
    "path": "meetings/2018/LDM-2018-10-03.md",
    "chars": 13918,
    "preview": "# C# Language Design Notes for Oct 3, 2018\n\n## Agenda\n\n1. How is the nullable context expressed?\n2. Async streams - whi"
  },
  {
    "path": "meetings/2018/LDM-2018-10-10.md",
    "chars": 2323,
    "preview": "\n# C# Language Design Notes for Oct 10, 2018\n\n_QOTD: C# has a long and proud tradition of being oblivious_\n\n## Agenda\n\n1"
  },
  {
    "path": "meetings/2018/LDM-2018-10-15.md",
    "chars": 2753,
    "preview": "\n# C# Language Design Notes for Oct 15, 2018\n\n## Agenda\n\n1. [Function pointers](https://github.com/dotnet/csharplang/blo"
  },
  {
    "path": "meetings/2018/LDM-2018-10-17.md",
    "chars": 3834,
    "preview": "\n# C# Language Design Notes for Oct 17, 2018\n\n## Agenda\n\n1. Open issues with default interface methods\n2. Target typed n"
  },
  {
    "path": "meetings/2018/LDM-2018-10-22.md",
    "chars": 4154,
    "preview": "# C# Language Design Notes for Oct 22, 2018\n\n## Agenda\n\nDiscuss two records proposals: \n\n1. [The existing old\none](https"
  },
  {
    "path": "meetings/2018/LDM-2018-10-24.md",
    "chars": 3603,
    "preview": "\n# C# Language Design Notes for Oct 24, 2018\n\n## Agenda\n\n1. [Adding Nullable Reference Type features to Nullable Value T"
  },
  {
    "path": "meetings/2018/LDM-2018-10-29.md",
    "chars": 4318,
    "preview": "\n# C# Language Design Notes for Oct 29, 2018\n\n## Agenda\n\n[Source-level opt-in to nullable reference types](https://githu"
  },
  {
    "path": "meetings/2018/LDM-2018-10-31.md",
    "chars": 1720,
    "preview": "\n# C# Design Review Notes for Oct 31, 2018\n\nThis was a review with the full design team (including Anders) to see how th"
  },
  {
    "path": "meetings/2018/LDM-2018-11-05.md",
    "chars": 3784,
    "preview": "\n# C# Language Design Notes for Nov 5, 2018\n\n## Agenda\n\n1. Where can #nullable go?\n2. Open issues with pattern matching\n"
  },
  {
    "path": "meetings/2018/LDM-2018-11-14.md",
    "chars": 3921,
    "preview": "\n# C# Language Design Notes for Nov 14, 2018\n\n## Agenda\n\n1. Base call syntax for default interface implementations\n2. Sw"
  },
  {
    "path": "meetings/2018/LDM-2018-11-28.md",
    "chars": 6912,
    "preview": "\n# C# LDM notes for Nov 28, 2018\n\n1. Are nullable annotations part of array specifiers?\n2. Cancellation of async-streams"
  },
  {
    "path": "meetings/2018/LDM-2018-12-03.md",
    "chars": 4407,
    "preview": "\n# C# LDM notes for Dec 3, 2018\n\n## Agenda\n\n1. `using` declaration open issues\n2. Return type of `Range` indexer on arra"
  },
  {
    "path": "meetings/2018/LDM-2018-12-05.md",
    "chars": 2978,
    "preview": "\n# C# LDM notes for Dec 5, 2018\n\n## Agenda\n\nTracked nullable states, their correspondence to source and the rules they f"
  },
  {
    "path": "meetings/2018/LDM-2018-12-12.md",
    "chars": 3312,
    "preview": "\n# C# LDM notes for Dec 12, 2018\n\n## Agenda\n\n1. Open issues with async streams\n2. Pattern dispose\n\n## Discussion\n\n### Ca"
  },
  {
    "path": "meetings/2018/README.md",
    "chars": 7310,
    "preview": "# C# Language Design Notes for 2018\n\nOverview of meetings and agendas for 2018\n\n\n## Jan 3, 2018\n[C# Language Design Note"
  },
  {
    "path": "meetings/2019/LDM-2019-01-07.md",
    "chars": 2626,
    "preview": "\n# C# Language Design Notes for January 7th, 2019\n\n## Agenda\n\nNullable:\n\n1. Variance in overriding/interface implementat"
  },
  {
    "path": "meetings/2019/LDM-2019-01-09.md",
    "chars": 3323,
    "preview": "\n# C# Language Design Notes for Jan. 9th, 2019\n\n## Agenda\n\n1. GetAsyncEnumerator signature\n2. Ambiguities in nullable ar"
  },
  {
    "path": "meetings/2019/LDM-2019-01-14.md",
    "chars": 2801,
    "preview": "\n# C# Language Design Notes for January 14th, 2019\n\n## Agenda\n\n1. Generating null-check for `parameter!`\n\n## Discussion\n"
  },
  {
    "path": "meetings/2019/LDM-2019-01-16.md",
    "chars": 2254,
    "preview": "\n# C# Language Design Notes for Jan. 16th, 2019\n\n## Agenda\n\n1. Shadowing in lambdas\n2. pattern-based disposal in `await "
  },
  {
    "path": "meetings/2019/LDM-2019-01-23.md",
    "chars": 1867,
    "preview": "\n# C# Language Design Meeting for Jan 23, 2019\n\n## Agenda\n\n Function pointers ([Updated proposal](https://github.com/dot"
  },
  {
    "path": "meetings/2019/LDM-2019-02-13.md",
    "chars": 4298,
    "preview": "# C# Language Design for February 13th, 2019\n\n## Agenda\n\nNullable Reference Types: Open LDM Issues https://github.com/do"
  },
  {
    "path": "meetings/2019/LDM-2019-02-20.md",
    "chars": 2407,
    "preview": "# C# Language Design Notes for Feb 20th, 2019\n\n## Agenda\n\n- Nullable Reference Types: Open LDM Issues https://github.com"
  },
  {
    "path": "meetings/2019/LDM-2019-02-25.md",
    "chars": 2341,
    "preview": "\n# C# Language Design Notes for Feb 25th, 2019\n\n## Agenda\n\nSemantics of `base()` calls in default interface implementati"
  },
  {
    "path": "meetings/2019/LDM-2019-02-27.md",
    "chars": 4442,
    "preview": "\n# C# Language Design Meeting for Feb. 27, 2019\n\n## Agenda\n\n1. Allow ObsoleteAttribute on property accessors\n2. More Def"
  },
  {
    "path": "meetings/2019/LDM-2019-03-04.md",
    "chars": 5190,
    "preview": "\n# C# Language Design Notes for March 4th, 2019\n\n## Agenda\n\n1. Nullable user studies\n2. Interpolated string and string.F"
  },
  {
    "path": "meetings/2019/LDM-2019-03-06.md",
    "chars": 5551,
    "preview": "\n# C# Language Design Meeting for March 6th, 2019\n\n## Agenda\n\nOpen issues:\n\n1. Pure checks in the switch expression\n2. N"
  },
  {
    "path": "meetings/2019/LDM-2019-03-13.md",
    "chars": 6298,
    "preview": "\n# C# Language Design Meeting for March 13, 2019\n\n## Agenda\n\n1. Interface \"reabstraction\" with default interface methods"
  },
  {
    "path": "meetings/2019/LDM-2019-03-19.md",
    "chars": 7014,
    "preview": "\n# C# LDM Notes for Mar 19, 2019\n\n## Agenda\n\nMVP Summit Live LDM w/ Q&A\n\nTopics:\n\n1. Records\n2. \"Extension interfaces\"/r"
  },
  {
    "path": "meetings/2019/LDM-2019-03-25.md",
    "chars": 4316,
    "preview": "# C# Design Review Notes for Mar 25, 2019\n\n## Agenda\n\nWe brought in the design review team to look at some of our recent"
  },
  {
    "path": "meetings/2019/LDM-2019-03-27.md",
    "chars": 3922,
    "preview": "\n# C# LDM Notes for Mar 27, 2019\n\n## Agenda\n\n1. Switch expression syntax\n\n1. Default interface implementations\n\n    1. R"
  },
  {
    "path": "meetings/2019/LDM-2019-04-01.md",
    "chars": 5134,
    "preview": "\n# C# Language Design Notes for April 1st, 2019\n\n## Agenda\n\n1. Pattern-based Index/Range translation\n\n2. Default interfa"
  },
  {
    "path": "meetings/2019/LDM-2019-04-03.md",
    "chars": 4390,
    "preview": "\n# C# Language Design Notes for Apr. 3, 2019\n\n## Agenda\n\n1. Ambiguous implementations/overrides with generic methods and"
  },
  {
    "path": "meetings/2019/LDM-2019-04-15.md",
    "chars": 5413,
    "preview": "\n# C# Language Design Notes for Apr. 15, 2019\n\n## Agenda\n\n1. CancellationToken in iterators\n2. Implied nullable constrai"
  },
  {
    "path": "meetings/2019/LDM-2019-04-22.md",
    "chars": 5232,
    "preview": "# C# Language Design Notes for April 22, 2019\n\n## Agenda\n\n1. Inferred nullable state from a finally block\n2. Implied con"
  }
]

// ... and 663 more files (download for full content)

About this extraction

This page contains the full source code of the dotnet/csharplang GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 863 files (5.9 MB), approximately 1.6M tokens, and a symbol index with 19 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!