{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/850","repository_url":"https://api.github.com/repos/dotnet/roslyn","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/850/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/850/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/850/events","html_url":"https://github.com/dotnet/roslyn/issues/850","id":58855325,"number":850,"title":"Proposal:  Property-scoped fields","user":{"login":"bondsbw","id":316704,"avatar_url":"https://avatars.githubusercontent.com/u/316704?v=3","gravatar_id":"","url":"https://api.github.com/users/bondsbw","html_url":"https://github.com/bondsbw","followers_url":"https://api.github.com/users/bondsbw/followers","following_url":"https://api.github.com/users/bondsbw/following{/other_user}","gists_url":"https://api.github.com/users/bondsbw/gists{/gist_id}","starred_url":"https://api.github.com/users/bondsbw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bondsbw/subscriptions","organizations_url":"https://api.github.com/users/bondsbw/orgs","repos_url":"https://api.github.com/users/bondsbw/repos","events_url":"https://api.github.com/users/bondsbw/events{/privacy}","received_events_url":"https://api.github.com/users/bondsbw/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/roslyn/labels/2%20-%20Ready","name":"2 - Ready","color":"CCCCCC"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Language%20Design","name":"Area-Language Design","color":"5319e7"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Feature%20Request","name":"Feature Request","color":"fc2929"}],"state":"open","locked":false,"assignee":{"login":"CyrusNajmabadi","id":4564579,"avatar_url":"https://avatars.githubusercontent.com/u/4564579?v=3","gravatar_id":"","url":"https://api.github.com/users/CyrusNajmabadi","html_url":"https://github.com/CyrusNajmabadi","followers_url":"https://api.github.com/users/CyrusNajmabadi/followers","following_url":"https://api.github.com/users/CyrusNajmabadi/following{/other_user}","gists_url":"https://api.github.com/users/CyrusNajmabadi/gists{/gist_id}","starred_url":"https://api.github.com/users/CyrusNajmabadi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CyrusNajmabadi/subscriptions","organizations_url":"https://api.github.com/users/CyrusNajmabadi/orgs","repos_url":"https://api.github.com/users/CyrusNajmabadi/repos","events_url":"https://api.github.com/users/CyrusNajmabadi/events{/privacy}","received_events_url":"https://api.github.com/users/CyrusNajmabadi/received_events","type":"User","site_admin":false},"milestone":null,"comments":58,"created_at":"2015-02-25T06:09:57Z","updated_at":"2016-02-13T20:35:24Z","closed_at":null,"body":"Here is a typical C# property that wraps a backing field, such that the property includes a little bit of additional behavior:\r\n```c#\r\nprivate string _myField;\r\npublic string MyProperty\r\n{\r\n    get { return _myField; }\r\n    set\r\n    {\r\n        _myField = value;\r\n        NotifyOfPropertyChange(nameof(MyProperty));\r\n    }\r\n}\r\n```\r\nWhenever I set ```MyProperty``` from within that class, I set the property instead of the field so that I ensure the extra behavior runs.  This is always the intended mechanism for writing this data.\r\n\r\n# Problem\r\n\r\nDuring maintenance, developers make changes to the class and sometimes manipulate the field directly, instead of setting the property as the class designer intended.  The result is that the additional behavior is not run, which leads to subtle bugs.  It is a simple mistake, one I would like to prevent if possible.\r\n\r\n# Solution\r\n\r\nOne way to fix this situation is to be able to scope fields to their associated property.  Within the property, the field can be fully manipulated as expected.  Outside of the property, the field is invisible.  Methods within that class are only able to interact with the property, which fully encapsulates the field.\r\n\r\nHere is an example of what this might look like:\r\n```c#\r\npublic string MyProperty\r\n{\r\n    string myField;\r\n    get { return myField; }\r\n    set\r\n    {\r\n        myField = value;\r\n        NotifyOfPropertyChange(nameof(MyProperty));\r\n    }\r\n}\r\n```\r\nIn this case, myField is fully encapsulated within MyProperty and nothing outside of MyProperty has access to myField directly.\r\n\r\n## Another option\r\n\r\nInstead of explicitly declaring the field, perhaps a keyword provides access to an implicit field identified by a keyword, such as ```field```.  This could look like the following:\r\n```c#\r\npublic string MyProperty\r\n{\r\n    get { return field; }\r\n    set\r\n    {\r\n        field = value;\r\n        NotifyOfPropertyChange(nameof(MyProperty));\r\n    }\r\n}\r\n```\r\n# Additional Considerations\r\n\r\nFields should probably be initialized in a way that bypasses the property setter, such as the following example.  The field should be initialized to null, but any future sets must have a non-null value:\r\n```c#\r\npublic string MyProperty\r\n{\r\n    string myField = null;\r\n    get { return myField; }\r\n    set\r\n    {\r\n        if (value == null) throw new ArgumentNullException(\"value\");\r\n        myField = value;\r\n    }\r\n}\r\n```\r\nShould constructors have special access to the backing field, to be able to set the field directly in the same manner?  Dot notation cannot work here.  Something different would be necessary, such as\r\n```c#\r\npublic MyClass(string val)\r\n{\r\n    MyProperty@myField = val;\r\n}\r\n```\r\n\r\nCan the property encapsulate multiple fields?  This might be useful in some contexts.  It would remove the second option that uses the ```field``` keyword."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/183748710","html_url":"https://github.com/dotnet/roslyn/issues/850#issuecomment-183748710","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/850","id":183748710,"user":{"login":"HaloFour","id":10102290,"avatar_url":"https://avatars.githubusercontent.com/u/10102290?v=3","gravatar_id":"","url":"https://api.github.com/users/HaloFour","html_url":"https://github.com/HaloFour","followers_url":"https://api.github.com/users/HaloFour/followers","following_url":"https://api.github.com/users/HaloFour/following{/other_user}","gists_url":"https://api.github.com/users/HaloFour/gists{/gist_id}","starred_url":"https://api.github.com/users/HaloFour/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/HaloFour/subscriptions","organizations_url":"https://api.github.com/users/HaloFour/orgs","repos_url":"https://api.github.com/users/HaloFour/repos","events_url":"https://api.github.com/users/HaloFour/events{/privacy}","received_events_url":"https://api.github.com/users/HaloFour/received_events","type":"User","site_admin":false},"created_at":"2016-02-13T20:35:24Z","updated_at":"2016-02-13T20:35:24Z","body":"@lachbaer \r\n\r\n> It's pseudocode, if you haven't noticed... But that is what is really going on under the hood!!!!\r\n\r\nIndeed, but it's not C#, so it doesn't have any bearing on a discussion regarding C# syntax. If C# had kept the members separate then you'd have an excellent point.\r\n\r\nAlso, that's only half of what's going on under the hood.  You'd notice that if you were to define the accessor methods by themselves that other CLR languages would not recognize them as properties.  Without the property member itself declared the methods would never be recognized as a property.\r\n\r\nAnd as mentioned, what the CLR and IL do under the hood aren't really that relevant.  C# takes numerous liberties in how it may implement certain features which don't exist in IL, and IL offers many features that C# doesn't expose at all.  Locals are a good example as to IL they are nothing but a flat indexed table of types.  Even the names don't survive beyond the debugger symbol metadata.  The IL assembly language does offer some concept of block scoping but it requires the developer to manually assign the index slots otherwise they are assigned in lexical order, and that information is lost during assembly.\r\n\r\nAnywho, I think we've pretty much exhausted our arguments for our opinions on the subject.  I'd say it's up to the language team to decide."}}