{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/13","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/13/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/13/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/13/events","html_url":"https://github.com/dotnet/roslyn/issues/13","id":54560025,"number":13,"title":"Feature request: Anonymous types that implement interfaces","user":{"login":"nvivo","id":202449,"avatar_url":"https://avatars.githubusercontent.com/u/202449?v=3","gravatar_id":"","url":"https://api.github.com/users/nvivo","html_url":"https://github.com/nvivo","followers_url":"https://api.github.com/users/nvivo/followers","following_url":"https://api.github.com/users/nvivo/following{/other_user}","gists_url":"https://api.github.com/users/nvivo/gists{/gist_id}","starred_url":"https://api.github.com/users/nvivo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nvivo/subscriptions","organizations_url":"https://api.github.com/users/nvivo/orgs","repos_url":"https://api.github.com/users/nvivo/repos","events_url":"https://api.github.com/users/nvivo/events{/privacy}","received_events_url":"https://api.github.com/users/nvivo/received_events","type":"User","site_admin":false},"labels":[{"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"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Language-C%23","name":"Language-C#","color":"207de5"}],"state":"open","locked":false,"assignee":{"login":"MadsTorgersen","id":6677272,"avatar_url":"https://avatars.githubusercontent.com/u/6677272?v=3","gravatar_id":"","url":"https://api.github.com/users/MadsTorgersen","html_url":"https://github.com/MadsTorgersen","followers_url":"https://api.github.com/users/MadsTorgersen/followers","following_url":"https://api.github.com/users/MadsTorgersen/following{/other_user}","gists_url":"https://api.github.com/users/MadsTorgersen/gists{/gist_id}","starred_url":"https://api.github.com/users/MadsTorgersen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MadsTorgersen/subscriptions","organizations_url":"https://api.github.com/users/MadsTorgersen/orgs","repos_url":"https://api.github.com/users/MadsTorgersen/repos","events_url":"https://api.github.com/users/MadsTorgersen/events{/privacy}","received_events_url":"https://api.github.com/users/MadsTorgersen/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/dotnet/roslyn/milestones/2","html_url":"https://github.com/dotnet/roslyn/milestones/Unknown","labels_url":"https://api.github.com/repos/dotnet/roslyn/milestones/2/labels","id":937398,"number":2,"title":"Unknown","description":"This represents work which is not planned for a specific release.\r\n\r\n<!---\r\n@huboard:{\"order\":3.5}\r\n-->\r\n","creator":{"login":"jaredpar","id":146967,"avatar_url":"https://avatars.githubusercontent.com/u/146967?v=3","gravatar_id":"","url":"https://api.github.com/users/jaredpar","html_url":"https://github.com/jaredpar","followers_url":"https://api.github.com/users/jaredpar/followers","following_url":"https://api.github.com/users/jaredpar/following{/other_user}","gists_url":"https://api.github.com/users/jaredpar/gists{/gist_id}","starred_url":"https://api.github.com/users/jaredpar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jaredpar/subscriptions","organizations_url":"https://api.github.com/users/jaredpar/orgs","repos_url":"https://api.github.com/users/jaredpar/repos","events_url":"https://api.github.com/users/jaredpar/events{/privacy}","received_events_url":"https://api.github.com/users/jaredpar/received_events","type":"User","site_admin":false},"open_issues":180,"closed_issues":38,"state":"open","created_at":"2015-01-15T20:46:02Z","updated_at":"2015-04-01T02:08:30Z","due_on":null,"closed_at":null},"comments":10,"created_at":"2015-01-16T10:21:12Z","updated_at":"2015-04-01T14:32:50Z","closed_at":null,"body":"It would be very useful if C# anonymous types could implement interfaces, including methods. This would make a huge difference when developing using interface driven design. It would also allow for very easy mocking in unit tests.\r\n\r\n```cs\r\ninterface IFooBar {\r\n    string Foo { get; }\r\n    int Bar(string s);\r\n}\r\n\r\nvoid MethodA () {\r\n    // explicitly typed\r\n    var myFooBar = new IFooBar {\r\n        Foo = \"xyz\",\r\n        Bar = s => s.Length\r\n    };\r\n\r\n    MethodB(myFooBar);\r\n}\r\n\r\nIFooBar MethodB(IFooBar fooBar) {\r\n    // implicit typed\r\n    return new {\r\n        Foo = \"abc\",\r\n        Bar = fooBar.Bar\r\n    };\r\n}\r\n```\r\n\r\nIn TypeScript and other dynamic languages, this has proven to be really useful and reduces a lot of boilerplate code. \r\n\r\nIt seems that implementing this in C# wouldn't break any rules as anonymous types are already classes internally, and the compiler could just make it implement the interface and use the same rules for checking type.\r\n\r\nThe only issue I can think right now is the method implementation. How to differ between a method and a property that is a delegate:\r\n\r\n```cs\r\ninterafce IFoo {\r\n    int Bar(int i);\r\n    Func<int, int> Baz { get; }\r\n}\r\n\r\nvoid IFoo GetFoo() {\r\n    return new {\r\n        Bar = i => 1, // ?\r\n        Baz = i => 2; // ?\r\n    }\r\n}\r\n```\r\n\r\nIt seems that from the perspective of the C# consumer it wouldn't make much difference, as both can be called using the same syntax (`obj.Bar()` or `obj.Baz()` ), but the compiler needs to know this.\r\n\r\nThis could be solved by either adding a new syntax to this implementation:\r\n\r\n```cs\r\nvoid IFoo GetFoo() {\r\n    return new {\r\n        Bar(int i) => 1,   // method\r\n        Baz = i => 2;  // deletage\r\n    }\r\n}\r\n``` \r\n\r\nOr by just defaulting to methods unless the interface calls for a property. That would make the first example with the same code valid, and I guess would make the syntax better."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/88506574","html_url":"https://github.com/dotnet/roslyn/issues/13#issuecomment-88506574","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/13","id":88506574,"user":{"login":"dsaf","id":3845650,"avatar_url":"https://avatars.githubusercontent.com/u/3845650?v=3","gravatar_id":"","url":"https://api.github.com/users/dsaf","html_url":"https://github.com/dsaf","followers_url":"https://api.github.com/users/dsaf/followers","following_url":"https://api.github.com/users/dsaf/following{/other_user}","gists_url":"https://api.github.com/users/dsaf/gists{/gist_id}","starred_url":"https://api.github.com/users/dsaf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dsaf/subscriptions","organizations_url":"https://api.github.com/users/dsaf/orgs","repos_url":"https://api.github.com/users/dsaf/repos","events_url":"https://api.github.com/users/dsaf/events{/privacy}","received_events_url":"https://api.github.com/users/dsaf/received_events","type":"User","site_admin":false},"created_at":"2015-04-01T14:32:50Z","updated_at":"2015-04-01T14:32:50Z","body":"@gafter Can records be declared within method body? I think this request is about not polluting the namespaces and creating explicit named types, rather than creating immutable classes with compact syntax. I believe these are different."}}