{"action":"created","issue":{"url":"https://api.github.com/repos/nsubstitute/NSubstitute/issues/488","repository_url":"https://api.github.com/repos/nsubstitute/NSubstitute","labels_url":"https://api.github.com/repos/nsubstitute/NSubstitute/issues/488/labels{/name}","comments_url":"https://api.github.com/repos/nsubstitute/NSubstitute/issues/488/comments","events_url":"https://api.github.com/repos/nsubstitute/NSubstitute/issues/488/events","html_url":"https://github.com/nsubstitute/NSubstitute/issues/488","id":391355566,"node_id":"MDU6SXNzdWUzOTEzNTU1NjY=","number":488,"title":"Allow setting of out parameters","user":{"login":"samcragg","id":1365438,"node_id":"MDQ6VXNlcjEzNjU0Mzg=","avatar_url":"https://avatars2.githubusercontent.com/u/1365438?v=4","gravatar_id":"","url":"https://api.github.com/users/samcragg","html_url":"https://github.com/samcragg","followers_url":"https://api.github.com/users/samcragg/followers","following_url":"https://api.github.com/users/samcragg/following{/other_user}","gists_url":"https://api.github.com/users/samcragg/gists{/gist_id}","starred_url":"https://api.github.com/users/samcragg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samcragg/subscriptions","organizations_url":"https://api.github.com/users/samcragg/orgs","repos_url":"https://api.github.com/users/samcragg/repos","events_url":"https://api.github.com/users/samcragg/events{/privacy}","received_events_url":"https://api.github.com/users/samcragg/received_events","type":"User","site_admin":false},"labels":[{"id":712764818,"node_id":"MDU6TGFiZWw3MTI3NjQ4MTg=","url":"https://api.github.com/repos/nsubstitute/NSubstitute/labels/feature-request","name":"feature-request","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-12-15T08:07:21Z","updated_at":"2018-12-27T14:39:03Z","closed_at":null,"author_association":"NONE","body":"I'm loving the work done under #401 to make the syntax for `ref`/`out` parameters much better, i.e. we can now say:\r\n```C#\r\nvar lookup = Substitute.For<ILookup>();\r\nlookup.TryLookup(\"hello\", out Arg.Any<string>())\r\n    .Returns(true);\r\n```\r\nHowever, the syntax to set the argument is still a bit clunky:\r\n```C#\r\nlookup.TryLookup(\"hello\", out Arg.Any<string>())\r\n    .Returns(x => { \r\n        x[1] = \"world!\";\r\n        return true;\r\n    });\r\n```\r\nI was wondering if you would be happy for me to submit a PR to take it one step further and let you change the argument, so I'm thinking of something like this:\r\n```C#\r\nlookup.TryLookup(\"hello\", out Arg.Set(\"world\"))\r\n    .Returns(true);\r\n```\r\n`Arg.Set` (happy for you to pick another name 🙂) would have the same match semantics as `Arg.Any` - if you wanted the ability to selectively set the argument I guess we could have an `Arg.SetWhen(condition, value)` method perhaps, though personally I've never had a need to do argument matching on `out` parameters as you have to set them in the method anyway plus if the user did want this they could switch back to the more verbose syntax.\r\n\r\nThoughts?"},"comment":{"url":"https://api.github.com/repos/nsubstitute/NSubstitute/issues/comments/450162030","html_url":"https://github.com/nsubstitute/NSubstitute/issues/488#issuecomment-450162030","issue_url":"https://api.github.com/repos/nsubstitute/NSubstitute/issues/488","id":450162030,"node_id":"MDEyOklzc3VlQ29tbWVudDQ1MDE2MjAzMA==","user":{"login":"zvirja","id":1074182,"node_id":"MDQ6VXNlcjEwNzQxODI=","avatar_url":"https://avatars1.githubusercontent.com/u/1074182?v=4","gravatar_id":"","url":"https://api.github.com/users/zvirja","html_url":"https://github.com/zvirja","followers_url":"https://api.github.com/users/zvirja/followers","following_url":"https://api.github.com/users/zvirja/following{/other_user}","gists_url":"https://api.github.com/users/zvirja/gists{/gist_id}","starred_url":"https://api.github.com/users/zvirja/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zvirja/subscriptions","organizations_url":"https://api.github.com/users/zvirja/orgs","repos_url":"https://api.github.com/users/zvirja/repos","events_url":"https://api.github.com/users/zvirja/events{/privacy}","received_events_url":"https://api.github.com/users/zvirja/received_events","type":"User","site_admin":false},"created_at":"2018-12-27T14:39:03Z","updated_at":"2018-12-27T14:39:03Z","author_association":"CONTRIBUTOR","body":"Hi David,\r\n\r\nMy initial thought was also to re-use the existing `Arg.Do()` instead of creating a new one 😉 \r\n\r\nHowever, after giving it more precise look, I found myself to be reluctant to add this feature. The main concern is that `Arg.XXX()` matcher becomes unsynchronized with `Returns()` callback, which could lead to confusion. Consider following sample:\r\n```c#\r\nlookup.TryLookup(\"hello\", ref Arg.Set(42)).Returns(true, false);\r\n```\r\n\r\nHow should we expect `Arg.Set()` to behave - assign only once, or for each call? Probably, when we return `false`, we don't want value to be assigned.\r\n\r\nOther sample:\r\n```c#\r\nlookup.TryLookup(\"hello\", ref Arg.Set(42))\r\n      .Returns(x => true, x => { x[1] = 44; return true; }, x => false)\r\n```\r\n\r\nShould `Returns()` override the value set by `Arg.Set()`?\r\n\r\nProbably, if we look even more, we could see other scenarios where feature isn't that obvious.\r\n\r\nGiven that `ref` and `out` scenarios are not that popular, I'd keep the existing way. Yes, it doesn't provide us with the compile-time safety, but it doesn't cause the confusion we might have due to `Arg.XXX()` and `Returns()` synchronization.\r\n\r\nInstead, we might solve this by analyzers from @tpodolak, so they catch when we assign value incorrectly (if we don't do that already...)."}}
{"actor":{"display_login":"zvirja"}}