{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/10678","repository_url":"https://api.github.com/repos/dotnet/roslyn","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/10678/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/10678/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/10678/events","html_url":"https://github.com/dotnet/roslyn/issues/10678","id":149410142,"number":10678,"title":"Proposal: Class Instance Variables","user":{"login":"bawNg","id":11107,"avatar_url":"https://avatars.githubusercontent.com/u/11107?v=3","gravatar_id":"","url":"https://api.github.com/users/bawNg","html_url":"https://github.com/bawNg","followers_url":"https://api.github.com/users/bawNg/followers","following_url":"https://api.github.com/users/bawNg/following{/other_user}","gists_url":"https://api.github.com/users/bawNg/gists{/gist_id}","starred_url":"https://api.github.com/users/bawNg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bawNg/subscriptions","organizations_url":"https://api.github.com/users/bawNg/orgs","repos_url":"https://api.github.com/users/bawNg/repos","events_url":"https://api.github.com/users/bawNg/events{/privacy}","received_events_url":"https://api.github.com/users/bawNg/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2016-04-19T10:00:44Z","updated_at":"2016-04-19T11:47:28Z","closed_at":null,"body":"Static variables in C# are severely limited compared to options available in some other languages, this makes static methods a lot less useful when it comes to derived classes. Making better use of the class level can allow for cleaner, more efficient implementations which require less code.\r\n\r\nI propose that a new kind of variable scope be created which allows declaring variables which are on a class level but are not shared between derived classes. This would give derived classes far more flexibility when it comes to making use of base class functionality. I have put together an example using the following minimal implementation to show why this would be useful.\r\n\r\n**Example Implementation**\r\n- A new keyword would be needed, I will use `substatic` for my example.\r\n- For each `substatic` variable in a derived class, the compiler would have to generate a static variable which has an identifier for the derived class appended to the name.\r\n- References made to `substatic` variables by base classes should resolve to the static variable which belongs to the most derived class for the given object.\r\n- The return value of a `substatic` method called on a derived class should be automatically cast to the derived type if the return type is the base class.\r\n\r\n**Example Usage**\r\n```csharp\r\npublic abstract class MongoDocument\r\n{\r\n    public static void Setup<T>()\r\n    {\r\n        var name = typeof(T).GetCustomAttribute<DatabaseAttribute>().Name;\r\n        database = MongoDriver.GetDatabase(name);\r\n        foreach (var field in typeof(T).GetFields())\r\n        {\r\n            fields.Add(new Field(field.GetType().GetCustomAttribute<FieldAttribute>().Name));\r\n        }\r\n    }\r\n\r\n    public substatic MongoDocument Find(int id) => database.Find(id);\r\n\r\n    protected substatic MongoDatabase database { get; private set; }\r\n    protected substatic List<Field> fields = new List<Field>();\r\n}\r\n\r\n[Database(\"users\")]\r\npublic class User : MongoDocument\r\n{\r\n    [Field(\"name\")]\r\n    public string Name;\r\n}\r\n\r\nstatic void RunTest()\r\n{\r\n    MongoDocument.Setup<User>();\r\n\r\n    // The MongoDocument instance is automatically cast to User when the substatic method\r\n    // is called on the User class\r\n    var user = User.Find(1);\r\n    Console.WriteLine(user.Name);\r\n}\r\n```\r\n\r\n\r\nAdditional improvements could include support for virtual static methods and support for expressions in a class body so that static fields/properties can be set and static methods can be called without requiring a static constructor."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/211876876","html_url":"https://github.com/dotnet/roslyn/issues/10678#issuecomment-211876876","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/10678","id":211876876,"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-04-19T11:47:28Z","updated_at":"2016-04-19T11:47:28Z","body":"If you keep the MongoDatabase separate from the document classes (which you should be doing anyway so that you can actually write proper tests) then there's no need for a language feature like this.  Simply have the database instance have a generic method to retrieve a document class, no casting or voodoo necessary."}}