{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/4586","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/4586/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/4586/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/4586/events","html_url":"https://github.com/dotnet/roslyn/issues/4586","id":101282959,"number":4586,"title":"Proposal: Intersection types","user":{"login":"MouseProducedGames","id":469640,"avatar_url":"https://avatars.githubusercontent.com/u/469640?v=3","gravatar_id":"","url":"https://api.github.com/users/MouseProducedGames","html_url":"https://github.com/MouseProducedGames","followers_url":"https://api.github.com/users/MouseProducedGames/followers","following_url":"https://api.github.com/users/MouseProducedGames/following{/other_user}","gists_url":"https://api.github.com/users/MouseProducedGames/gists{/gist_id}","starred_url":"https://api.github.com/users/MouseProducedGames/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MouseProducedGames/subscriptions","organizations_url":"https://api.github.com/users/MouseProducedGames/orgs","repos_url":"https://api.github.com/users/MouseProducedGames/repos","events_url":"https://api.github.com/users/MouseProducedGames/events{/privacy}","received_events_url":"https://api.github.com/users/MouseProducedGames/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"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":19,"created_at":"2015-08-16T17:36:42Z","updated_at":"2015-10-22T01:26:27Z","closed_at":null,"body":"Let's say you have an IQuadruped interface:\r\n```\r\npublic interface IQuadruped\r\n{\r\n    public Leg FrontLeftLeg { get; set; }\r\n    public Leg FrontRightLeg { get; set; }\r\n    public Leg BackLeftLeg { get; set; }\r\n    public Leg BackRightLeg { get; set; }\r\n    // ...\r\n}\r\n```\r\nand an IMammal interface:\r\n```\r\npublic interface IMammal\r\n{\r\n    public NumberOfHairs { get; }\r\n    // ...\r\n}\r\n```\r\nAnd, of course, some classes implementing both interfaces.\r\n```\r\npublic class Dog : IQuadruped, IMammal, ... { // ... }\r\npublic class Cat : IQuadruped, IMammal, ... { // ... }\r\npublic class Platypus : IQuadruped, IMammal, IReallyWeird, ... { // ... }\r\n// ...\r\n```\r\n\r\nNow you want to operate on all the quadrupedal mammals in your enumerable of animals:\r\n```\r\nforeach (var animal in animals.Where(a => a is IQuadruped && a is IAnimal))\r\n{\r\n    IQuadruped qAnimal = (IQuadruped)animal;\r\n    IMammal mAnimal = (IMammal)animal;\r\n    // Code involving both interfaces here.\r\n}\r\n```\r\nAnd, of course, the complexity goes up the more interfaces you want to check.\r\n\r\nHowever, if, instead, you had:\r\n```\r\nforeach (var animal in animals.Select(a => a as I<IQuadruped, IAnimal>).Select(a => !object.Equals(a, null))\r\n{\r\n    // animal is now of type I<IQuadruped, IAnimal>.\r\n    // Any operation supported by either interface is supported by the combined interface.\r\n    // And you only have to reference one variable.\r\n}\r\n```\r\n\r\nIn short, ```I<Interface, ...>``` combines interfaces into one interface, without having to create an IQuadrupedMammal interface, going back into your code, and refactoring. Which may not be possible, or may be impractical. IQuadrupedMammalReallyWeirdFromAustralia..."},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/150071089","html_url":"https://github.com/dotnet/roslyn/issues/4586#issuecomment-150071089","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/4586","id":150071089,"user":{"login":"ufcpp","id":3760955,"avatar_url":"https://avatars.githubusercontent.com/u/3760955?v=3","gravatar_id":"","url":"https://api.github.com/users/ufcpp","html_url":"https://github.com/ufcpp","followers_url":"https://api.github.com/users/ufcpp/followers","following_url":"https://api.github.com/users/ufcpp/following{/other_user}","gists_url":"https://api.github.com/users/ufcpp/gists{/gist_id}","starred_url":"https://api.github.com/users/ufcpp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ufcpp/subscriptions","organizations_url":"https://api.github.com/users/ufcpp/orgs","repos_url":"https://api.github.com/users/ufcpp/repos","events_url":"https://api.github.com/users/ufcpp/events{/privacy}","received_events_url":"https://api.github.com/users/ufcpp/received_events","type":"User","site_admin":false},"created_at":"2015-10-22T01:26:27Z","updated_at":"2015-10-22T01:26:27Z","body":"I like this concept, but IMO, its syntax should be consistent with that of generic constraints. How about the following:\r\n\r\n```\r\nx is T t where T : IQuadruped, IMammal\r\n```\r\n"}}