{"action":"created","issue":{"url":"https://api.github.com/repos/bchavez/Bogus/issues/124","repository_url":"https://api.github.com/repos/bchavez/Bogus","labels_url":"https://api.github.com/repos/bchavez/Bogus/issues/124/labels{/name}","comments_url":"https://api.github.com/repos/bchavez/Bogus/issues/124/comments","events_url":"https://api.github.com/repos/bchavez/Bogus/issues/124/events","html_url":"https://github.com/bchavez/Bogus/issues/124","id":295101543,"number":124,"title":"Randomly Null","user":{"login":"Mardoxx","id":239665,"avatar_url":"https://avatars3.githubusercontent.com/u/239665?v=4","gravatar_id":"","url":"https://api.github.com/users/Mardoxx","html_url":"https://github.com/Mardoxx","followers_url":"https://api.github.com/users/Mardoxx/followers","following_url":"https://api.github.com/users/Mardoxx/following{/other_user}","gists_url":"https://api.github.com/users/Mardoxx/gists{/gist_id}","starred_url":"https://api.github.com/users/Mardoxx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Mardoxx/subscriptions","organizations_url":"https://api.github.com/users/Mardoxx/orgs","repos_url":"https://api.github.com/users/Mardoxx/repos","events_url":"https://api.github.com/users/Mardoxx/events{/privacy}","received_events_url":"https://api.github.com/users/Mardoxx/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-07T11:24:47Z","updated_at":"2018-02-07T18:48:39Z","closed_at":null,"author_association":"NONE","body":"Would producing randomly nullable objects for reference and `Nullable<T>` types be useful? At the moment I've just been filling my nullables with values.\r\n\r\nNot sure what sort of API would be appropriate? I think difficulty lies with `Nullable<T>` being a struct 😢 Anyone got any clever ideas?\r\n\r\nFor `Nullable<T>` perhaps just a method on `Randomizer` would be okay?\r\n\r\n```csharp\r\nnamespace Bogus\r\n{\r\n    public static class RandomizerExtensions\r\n    {\r\n        public static T? Nullable<T>(this Randomizer randomizer, T? value)\r\n            where T : struct\r\n        {\r\n            return randomizer.Bool() ? value : null;\r\n        }\r\n\r\n        public static T? Nullable<T>(this Randomizer randomizer, T value)\r\n            where T : struct\r\n        {\r\n            return randomizer.Nullable(new T?(value));\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nBut that leads to a more messy setup, e.g.\r\n`faker.RuleFor(x => x.Guid, x => x.Random.Nullable(x.Random.Uuid()))`\r\n\r\nHow about a `NullableRandomizer`  class which does the same as `Randomizer` but randomly returns null? Then you could do something like `x.Random.Nullable.Bool()`\r\n\r\nMaybe a method such as `x.Random.Nullable.Value<T>(T value) where T : class` for reference types, and `x.Random.Nullable.Value<T>() where T : struct` for enums?\r\n\r\nJust some ideas! 😄 \r\n"},"comment":{"url":"https://api.github.com/repos/bchavez/Bogus/issues/comments/363870206","html_url":"https://github.com/bchavez/Bogus/issues/124#issuecomment-363870206","issue_url":"https://api.github.com/repos/bchavez/Bogus/issues/124","id":363870206,"user":{"login":"bchavez","id":478118,"avatar_url":"https://avatars1.githubusercontent.com/u/478118?v=4","gravatar_id":"","url":"https://api.github.com/users/bchavez","html_url":"https://github.com/bchavez","followers_url":"https://api.github.com/users/bchavez/followers","following_url":"https://api.github.com/users/bchavez/following{/other_user}","gists_url":"https://api.github.com/users/bchavez/gists{/gist_id}","starred_url":"https://api.github.com/users/bchavez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bchavez/subscriptions","organizations_url":"https://api.github.com/users/bchavez/orgs","repos_url":"https://api.github.com/users/bchavez/repos","events_url":"https://api.github.com/users/bchavez/events{/privacy}","received_events_url":"https://api.github.com/users/bchavez/received_events","type":"User","site_admin":false},"created_at":"2018-02-07T18:48:39Z","updated_at":"2018-02-07T18:48:39Z","author_association":"OWNER","body":"Hi @Mardoxx ,\r\n\r\nGood and challenging scenario here. One other idea is to *nullify* the result with an `.OrNull()` extension method like this:\r\n\r\n```csharp\r\npublic static class ObjectExtensions\r\n{\r\n   public static T? OrNull<T>(this T? value)\r\n      where T : struct\r\n   {\r\n      return value.GetHashCode() % 2 == 0 ? value : null;\r\n   }\r\n\r\n   public static T? OrNull<T>(this T value)\r\n      where T : struct\r\n   {\r\n      return value.GetHashCode() % 2 == 0 ? (T?)value : null;\r\n   }\r\n}\r\n```\r\nThen your rule code starts looking like:\r\n```csharp\r\n[Fact]\r\npublic void test_nullable()\r\n{\r\n   var faker = new Faker<Person>()\r\n      .RuleFor(p => p.Guid, f => f.Random.Uuid().OrNull())\r\n      .RuleFor(p => p.Name, f => f.Person.FullName);\r\n\r\n   console.Dump(faker.Generate(20));\r\n}\r\n```\r\nSetups like `.RuleFor(p => p.Guid, f => f.Random.Uuid().OrNull())` look pretty clean to me. What do you think?\r\n\r\nIf I recall correctly I think `Guid`'s `.GetHashCode()` implementation is deterministic. That is to say, `Guid.Empty` is always 0 and\r\n```\r\nnew Guid(\"82b32a64-78aa-415d-b50f-6647bf31c82e\").GetHashCode() ==\r\nnew Guid(\"82b32a64-78aa-415d-b50f-6647bf31c82e\").GetHashCode()\r\n```\r\n\r\nSo, that's pretty cool. You get determinism in `Guid.GetHashCode()` for free without the need for sourcing deterministic randomness from a `Randomizer`.\r\n\r\nThe only \"potential\" problem with this approach is probably the non-determinism of `null` relying on `GetHashCode()` for some reference type `T`.  \r\n\r\nAlternatively, you could new up a `new Randomizer()` in a static field in `ObjectExtensions` and use that but you'd be relying on the global static seed.\r\n\r\n---\r\n\r\nAlso, if nullable `Guid?` is 90% of cases, I'd never shy away from keeping it simple:\r\n\r\n```csharp\r\npublic static class ObjectExtensions\r\n{\r\n   public static Guid? UuidNullable(this Randomizer r)\r\n   {\r\n      return r.Bool() ? r.Uuid() : (Guid?)null;\r\n   }\r\n}\r\n```\r\n```csharp\r\nvar faker = new Faker<Person>()\r\n   .RuleFor(p => p.Guid, f => f.Random.UuidNullable())\r\n   .RuleFor(p => p.Name, f => f.Person.FullName);\r\n```\r\n\r\nHope that helps! \r\n\r\nThanks,\r\nBrian\r\n\r\n:car: :blue_car: ***[\"Let the good times roll...\"](https://www.youtube.com/watch?v=7BDBzgHXf64)***"}}
{"actor":{"display_login":"bchavez"}}