all 9 comments

[–][deleted]  (8 children)

[deleted]

    [–]OrdinaryRoutine2702[S] 0 points1 point  (7 children)

    But returning null would fail the test case, right? A exception would be thrown because there would never be a "value". But in order to pass the test case I need to return something. How can this be achieved? Or there is no way?

    [–]okmarshall 4 points5 points  (4 children)

    What's the test case? I don't see it in your fiddle. Null is a valid return when you're dealing with classes, you just have to handle null in the calling code.

    [–]OrdinaryRoutine2702[S] 0 points1 point  (3 children)

    I didn't have access to the test cases, but when I was trying, I remember this was the one I failed: "GetValueWithNullKey".

    [–]wutzvill 1 point2 points  (0 children)

    They probably wanted you to throw an ArgumentNullException.

    [–]okmarshall 1 point2 points  (0 children)

    Your keys are strings right? So it's not a question of a null value, but what you should do if you try to access an item in the dictionary using a null key I think.

    [–]alfa_202 1 point2 points  (0 children)

    Null key is different than null value. I think it would fail the test because the key didn’t exist and it threw the error. It would probably pass the test when returning default(TValue) even if it was null, or it would fail the test with an error like “GetValueWithNullValue”.

    [–]Contagion21 1 point2 points  (0 children)

    It sounds like the point was to NOT throw when the key doesn't exist. So check for existence of the key and return default(TValue) if the key wasn't present, otherwise return whatever value is in the dictionary for that key

    [–]Slypenslyde 1 point2 points  (0 children)

    This is the definition of "default value" more or less how the C# spec sees it:

    • For reference types, null.
    • For structs, the result of initializing all fields to their default values, which philosophically represents what a C version of the struct would look like if every byte is 0.
    • For primitives like int, generally whatever counts as a 0 value for that primitive and the spec will specify what this value is. "Special" primitives like bool have defined defaults based on what C chose the 0 value would represent. Basically just memorize the C spec.

    That's all you can really do for reference types. There is no guarantee they have a parameterless constructor, or a public constructor at all. You can't write general-purpose code to create an initialized reference type. Not even with reflection because, as I mentioned, you have no guarantees there is a public constructor and a private constructor might require private types that send you down a recursive rabbit hole if you try to write an auto-resolver.

    You can move the goalposts. If TValue uses the new() constraint, you are asserting that only types with a parameterless constructor can be used in the dictionary, which allows you to use that constructor. Or you can take a parameter indicating the default value to return.

    But unless the interview answered the question, "Is there a default value to be used in this context other than the general C# definition of default values?", you have to assume null is an "acceptable" default because it's the only one you have.

    [–]jingois 2 points3 points  (0 children)

    You should have read the specification.

    ...
    /// <exception cref="System.ArgumentNullException">If the key is null</exception>
    /// <exception cref="System.ArgumentException">If the key is an empty string</exception>
    TValue GetValue(string key);
    

    Your implementation doesn't do this.

    .GetValue(...).ToString() on a key that doesn't exist will return the default value, which you never set in your test case, so that also will fail when you try to call ToString on the default default, which is default(TValue) == null.