Are (c#) dictionaries an Anti Pattern?Finding a definition for this anti-patternWhat are the relative advantages of dictionaries versus databases?TDD Mock call verification - is it an anti-pattern?Reference Passing Style Anti PatternPassing an object into a method which changes the object, is it a common (anti-) pattern?Efficiency of C# dictionariesA better way than O(n^2) for traversing a dictionary of dictionaries.Dictionary of dictionaries design in C#Does this anti-pattern have a name?

Pen test results for web application include a file from a forbidden directory that is not even used or referenced

Recommended Breathing Exercises to Play Woodwinds

How do I insert two edge loops equally spaced from the edges?

Defending Castle from Zombies

Did anybody find out it was Anakin who blew up the command center?

How to force GCC to assume that a floating-point expression is non-negative?

What's the point of fighting monsters in Zelda BoTW?

How to prevent a hosting company from accessing a VM's encryption keys?

Are strlen optimizations really needed in glibc?

Does trying to charm an uncharmable creature cost a spell slot?

Availability Groups automatic failover is not so automatic

Dual of a bimodule

Notice period 60 days but I need to join in 45 days

Alternatives to Network Backup

How to say "I only speak one which is English." in French?

Why did Lucius make a deal out of Buckbeak hurting Draco but not about Draco being turned into a ferret?

Can I get a PhD for developing an educational software?

What is the name of this plot that has rows with two connected dots?

Are there any to-scale diagrams of the TRAPPIST-1 system?

Units in general relativity

Is a memoized pure function itself considered pure?

Fantasy Macro Economics: What would Merfolk Trade?

Is a Centaur PC considered an animal when calculating carrying capacity for vehicles?

Is the Amazon rainforest the "world's lungs"?



Are (c#) dictionaries an Anti Pattern?


Finding a definition for this anti-patternWhat are the relative advantages of dictionaries versus databases?TDD Mock call verification - is it an anti-pattern?Reference Passing Style Anti PatternPassing an object into a method which changes the object, is it a common (anti-) pattern?Efficiency of C# dictionariesA better way than O(n^2) for traversing a dictionary of dictionaries.Dictionary of dictionaries design in C#Does this anti-pattern have a name?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








4















I find myself often looking up questions online, and many solutions include dictionaries. However, whenever I try to implement them, I get this horrible reek in my code. For example every time I want to use a value:



int x;
if (dict.TryGetValue("key", out x)
DoSomethingWith(x);



That's 4 lines of code to essentially do the following: DoSomethingWith(dict["key"])



I've heard that using the out keyword is an anti pattern because it makes functions mutate their parameters.



Also, I find myself often needing a "reversed" dictionary, where I flip the keys and values.



Similarly, I often would like to iterate through the items in a dictionary and find myself converting keys or values to lists etc to do this better.



I feel like there's almost always a better, more elegant way of using dictionaries, But I'm at a loss.










share|improve this question





















  • 2





    Other ways may exist but I generally use a ContainsKey first before trying to get a value.

    – Robbie Dee
    8 hours ago











  • If DoSomethingWith(x) were an extension method you could technically do: dict.TryGetValue("key", out int x); x?.DoSomething(); Handles the case where "key" does not exist, and still does something with x like the original code did. But Dictionary itself is not an antipattern. It's a collection, so its all about how you use it.

    – Berin Loritsch
    8 hours ago











  • Honestly, with a few exceptions, if you know what your dictionary keys are ahead of time, there probably is a better way. If you don't know, the dict keys shouldn't generally be hard-coded at all. Dictionaries are useful for working with semi-structured objects or data where the fields are at least mostly orthogonal to the application. IMO, the closer those fields get to being relevant business/domain concepts, the less helpful dictionaries become for working with those concepts.

    – svidgen
    7 hours ago







  • 2





    @RobbieDee: you have to be careful when you do that though, as doing so creates a race condition. It's possible the key could be removed between calling ContainsKey and getting the value.

    – whatsisname
    6 hours ago







  • 3





    @whatsisname: Under those conditions, a ConcurrentDictionary would be more suitable. Collections in the System.Collections.Generic namespace are not thread-safe.

    – Robert Harvey
    3 hours ago


















4















I find myself often looking up questions online, and many solutions include dictionaries. However, whenever I try to implement them, I get this horrible reek in my code. For example every time I want to use a value:



int x;
if (dict.TryGetValue("key", out x)
DoSomethingWith(x);



That's 4 lines of code to essentially do the following: DoSomethingWith(dict["key"])



I've heard that using the out keyword is an anti pattern because it makes functions mutate their parameters.



Also, I find myself often needing a "reversed" dictionary, where I flip the keys and values.



Similarly, I often would like to iterate through the items in a dictionary and find myself converting keys or values to lists etc to do this better.



I feel like there's almost always a better, more elegant way of using dictionaries, But I'm at a loss.










share|improve this question





















  • 2





    Other ways may exist but I generally use a ContainsKey first before trying to get a value.

    – Robbie Dee
    8 hours ago











  • If DoSomethingWith(x) were an extension method you could technically do: dict.TryGetValue("key", out int x); x?.DoSomething(); Handles the case where "key" does not exist, and still does something with x like the original code did. But Dictionary itself is not an antipattern. It's a collection, so its all about how you use it.

    – Berin Loritsch
    8 hours ago











  • Honestly, with a few exceptions, if you know what your dictionary keys are ahead of time, there probably is a better way. If you don't know, the dict keys shouldn't generally be hard-coded at all. Dictionaries are useful for working with semi-structured objects or data where the fields are at least mostly orthogonal to the application. IMO, the closer those fields get to being relevant business/domain concepts, the less helpful dictionaries become for working with those concepts.

    – svidgen
    7 hours ago







  • 2





    @RobbieDee: you have to be careful when you do that though, as doing so creates a race condition. It's possible the key could be removed between calling ContainsKey and getting the value.

    – whatsisname
    6 hours ago







  • 3





    @whatsisname: Under those conditions, a ConcurrentDictionary would be more suitable. Collections in the System.Collections.Generic namespace are not thread-safe.

    – Robert Harvey
    3 hours ago














4












4








4


1






I find myself often looking up questions online, and many solutions include dictionaries. However, whenever I try to implement them, I get this horrible reek in my code. For example every time I want to use a value:



int x;
if (dict.TryGetValue("key", out x)
DoSomethingWith(x);



That's 4 lines of code to essentially do the following: DoSomethingWith(dict["key"])



I've heard that using the out keyword is an anti pattern because it makes functions mutate their parameters.



Also, I find myself often needing a "reversed" dictionary, where I flip the keys and values.



Similarly, I often would like to iterate through the items in a dictionary and find myself converting keys or values to lists etc to do this better.



I feel like there's almost always a better, more elegant way of using dictionaries, But I'm at a loss.










share|improve this question
















I find myself often looking up questions online, and many solutions include dictionaries. However, whenever I try to implement them, I get this horrible reek in my code. For example every time I want to use a value:



int x;
if (dict.TryGetValue("key", out x)
DoSomethingWith(x);



That's 4 lines of code to essentially do the following: DoSomethingWith(dict["key"])



I've heard that using the out keyword is an anti pattern because it makes functions mutate their parameters.



Also, I find myself often needing a "reversed" dictionary, where I flip the keys and values.



Similarly, I often would like to iterate through the items in a dictionary and find myself converting keys or values to lists etc to do this better.



I feel like there's almost always a better, more elegant way of using dictionaries, But I'm at a loss.







c# anti-patterns code-smell dictionary out-parameters






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 8 hours ago









Robbie Dee

8,3712 gold badges16 silver badges48 bronze badges




8,3712 gold badges16 silver badges48 bronze badges










asked 8 hours ago









Adam BAdam B

2141 silver badge10 bronze badges




2141 silver badge10 bronze badges










  • 2





    Other ways may exist but I generally use a ContainsKey first before trying to get a value.

    – Robbie Dee
    8 hours ago











  • If DoSomethingWith(x) were an extension method you could technically do: dict.TryGetValue("key", out int x); x?.DoSomething(); Handles the case where "key" does not exist, and still does something with x like the original code did. But Dictionary itself is not an antipattern. It's a collection, so its all about how you use it.

    – Berin Loritsch
    8 hours ago











  • Honestly, with a few exceptions, if you know what your dictionary keys are ahead of time, there probably is a better way. If you don't know, the dict keys shouldn't generally be hard-coded at all. Dictionaries are useful for working with semi-structured objects or data where the fields are at least mostly orthogonal to the application. IMO, the closer those fields get to being relevant business/domain concepts, the less helpful dictionaries become for working with those concepts.

    – svidgen
    7 hours ago







  • 2





    @RobbieDee: you have to be careful when you do that though, as doing so creates a race condition. It's possible the key could be removed between calling ContainsKey and getting the value.

    – whatsisname
    6 hours ago







  • 3





    @whatsisname: Under those conditions, a ConcurrentDictionary would be more suitable. Collections in the System.Collections.Generic namespace are not thread-safe.

    – Robert Harvey
    3 hours ago













  • 2





    Other ways may exist but I generally use a ContainsKey first before trying to get a value.

    – Robbie Dee
    8 hours ago











  • If DoSomethingWith(x) were an extension method you could technically do: dict.TryGetValue("key", out int x); x?.DoSomething(); Handles the case where "key" does not exist, and still does something with x like the original code did. But Dictionary itself is not an antipattern. It's a collection, so its all about how you use it.

    – Berin Loritsch
    8 hours ago











  • Honestly, with a few exceptions, if you know what your dictionary keys are ahead of time, there probably is a better way. If you don't know, the dict keys shouldn't generally be hard-coded at all. Dictionaries are useful for working with semi-structured objects or data where the fields are at least mostly orthogonal to the application. IMO, the closer those fields get to being relevant business/domain concepts, the less helpful dictionaries become for working with those concepts.

    – svidgen
    7 hours ago







  • 2





    @RobbieDee: you have to be careful when you do that though, as doing so creates a race condition. It's possible the key could be removed between calling ContainsKey and getting the value.

    – whatsisname
    6 hours ago







  • 3





    @whatsisname: Under those conditions, a ConcurrentDictionary would be more suitable. Collections in the System.Collections.Generic namespace are not thread-safe.

    – Robert Harvey
    3 hours ago








2




2





Other ways may exist but I generally use a ContainsKey first before trying to get a value.

– Robbie Dee
8 hours ago





Other ways may exist but I generally use a ContainsKey first before trying to get a value.

– Robbie Dee
8 hours ago













If DoSomethingWith(x) were an extension method you could technically do: dict.TryGetValue("key", out int x); x?.DoSomething(); Handles the case where "key" does not exist, and still does something with x like the original code did. But Dictionary itself is not an antipattern. It's a collection, so its all about how you use it.

– Berin Loritsch
8 hours ago





If DoSomethingWith(x) were an extension method you could technically do: dict.TryGetValue("key", out int x); x?.DoSomething(); Handles the case where "key" does not exist, and still does something with x like the original code did. But Dictionary itself is not an antipattern. It's a collection, so its all about how you use it.

– Berin Loritsch
8 hours ago













Honestly, with a few exceptions, if you know what your dictionary keys are ahead of time, there probably is a better way. If you don't know, the dict keys shouldn't generally be hard-coded at all. Dictionaries are useful for working with semi-structured objects or data where the fields are at least mostly orthogonal to the application. IMO, the closer those fields get to being relevant business/domain concepts, the less helpful dictionaries become for working with those concepts.

– svidgen
7 hours ago






Honestly, with a few exceptions, if you know what your dictionary keys are ahead of time, there probably is a better way. If you don't know, the dict keys shouldn't generally be hard-coded at all. Dictionaries are useful for working with semi-structured objects or data where the fields are at least mostly orthogonal to the application. IMO, the closer those fields get to being relevant business/domain concepts, the less helpful dictionaries become for working with those concepts.

– svidgen
7 hours ago





2




2





@RobbieDee: you have to be careful when you do that though, as doing so creates a race condition. It's possible the key could be removed between calling ContainsKey and getting the value.

– whatsisname
6 hours ago






@RobbieDee: you have to be careful when you do that though, as doing so creates a race condition. It's possible the key could be removed between calling ContainsKey and getting the value.

– whatsisname
6 hours ago





3




3





@whatsisname: Under those conditions, a ConcurrentDictionary would be more suitable. Collections in the System.Collections.Generic namespace are not thread-safe.

– Robert Harvey
3 hours ago






@whatsisname: Under those conditions, a ConcurrentDictionary would be more suitable. Collections in the System.Collections.Generic namespace are not thread-safe.

– Robert Harvey
3 hours ago











6 Answers
6






active

oldest

votes


















8















Dictionaries (C# or otherwise) are simply a container where you look up a value based on a key. In many languages it's more correctly identified as a Map with the most common implementation being a HashMap.



The problem to consider is what happens when a key does not exist. Some languages behave by returning null or nil or some other equivalent value. Silently defaulting to a value instead of informing you that a value does not exist.



For better or for worse, the C# library designers came up with an idiom to deal with the behavior. They reasoned that the default behavior for looking up a value that does not exist is to throw an exception. If you want to avoid exceptions, then you can use the Try variant. It's the same approach they use for parsing strings into integers or date/time objects. Essentially, the impact is like this:



T count = int.Parse("12T45"); // throws exception

if (int.TryParse("12T45", out count))

// Does not throw exception



And that carried forward to the dictionary, whose indexer delegates to Get(index):



var myvalue = dict["12345"]; // throws exception
myvalue = dict.Get("12345"); // throws exception

if (dict.TryGet("12345", out myvalue))

// Does not throw exception



This is simply the way the language is designed.




Should out variables be discouraged?



C# isn't the first language to have them, and they have their purpose in specific situations. If you are trying to build a highly concurrent system, then you cannot use out variables at the concurrency boundaries.



In many ways, if there is an idiom that is espoused by the language and core library providers, I try to adopt those idioms in my APIs. That makes the API feel more consistent and at home in that language. So a method written in Ruby isn't going to look like a method written in C#, C, or Python. They each have a preferred way of building code, and working with that helps the users of your API learn it more quickly.




Are Maps in General an Anti-pattern?



They have their purpose, but many times they may be the wrong solution for the purpose you have. Particularly if you have a bi-directional mapping you need. There are many containers and ways of organizing data. There are many approaches that you can use, and sometimes you need to think a bit before you pick that container.



If you have a very short list of bi-directional mapping values, then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping.



Think of the problem domain, and pick the most appropriate tool for the job. If there isn't one, then create it.






share|improve this answer

























  • "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

    – Blrfl
    3 hours ago











  • If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

    – Berin Loritsch
    3 hours ago











  • It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

    – Blrfl
    1 hour ago


















6















This is neither a code smell nor an anti-pattern, as using TryGet-style functions with an out parameter is idiomatic C#. However, there are 3 options provided in C# to work with a Dictionary, so should you be sure you are using the correct one for your situation. I think I know where the rumor of there being a problem using an out parameter comes from, so I'll handle that at the end.



What features to use when working with a C# Dictionary:



  1. If you are sure the key will be in the Dictionary, use the Item[TKey] property

  2. If the key should generally be in the Dictionary, but it is bad/rare/problematic that it is not there, you should use Try...Catch so that an error will be raised and then you can try to handle the error gracefully

  3. If you are not sure the key will be in the Dictionary, use TryGet with the out parameter

To justify this, one need only refer to the documentation for Dictionary TryGetValue, under "Remarks":




This method combines the functionality of the ContainsKey method and the Item[TKey] property.



...



Use the TryGetValue method if your code frequently attempts to access
keys that are not in the dictionary. Using this method is more
efficient than catching the KeyNotFoundException thrown by the
Item[TKey] property.



This method approaches an O(1) operation.




The whole reason TryGetValue exists is to act as a more convenient way to use ContainsKey and Item[TKey], while avoiding having to search the dictionary twice - so pretending it doesn't exist and doing the two things it does manually is a rather awkward choice.



In practice, I rarely have ever used a raw Dictionary, due to this simple maxim: choose the most generic class/container that gives you the functionality you need. Dictionary was not designed to look up by value rather than by key (for example), so if that is something you want it may make more sense to use an alternate structure. I think I may have used Dictionary one time in the last year-long development project I did, simply because it was rarely the right tool for the job I was trying to do. Dictionary is certainly not the Swiss Army knife of the C# toolbox.



What's wrong with out parameters?



CA1021: Avoid out parameters




Although return values are commonplace and heavily used, the correct
application of out and ref parameters requires intermediate design and
coding skills. Library architects who design for a general audience
should not expect users to master working with out or ref parameters.




I'm guessing that's where you heard that out parameters were something like an anti-pattern. As with all rules, you should read closer to understand the 'why', and in this case there is even an explicit mention of how the Try pattern does not violate the rule:




Methods that implement the Try pattern, such as
System.Int32.TryParse, do not raise this violation.







share|improve this answer
































    4















    Some good answers here on the general principles of hashtables/dictionaries. But I thought I'd touch on your code example,



    int x;
    if (dict.TryGetValue("key", out x)

    DoSomethingWith(x);



    As of C# 7 (which I think is around two years old), that can be simplified to:



    if (dict.TryGetValue("key", out var x) 

    DoSomethingWith(x);



    And of course it could be reduced to one line:



    if (dict.TryGetValue("key", out var x) DoSomethingWith(x);


    If you have a default value for when the key doesn't exist, it can become:



    DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);


    So you can achieve compact forms by using reasonably recent language additions.






    share|improve this answer




















    • 1





      Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

      – BrianH
      34 mins ago



















    3















    The TryGetValue() construct is only necessary if you don't know whether "key" is present as a key within the dictionary or not, otherwise DoSomethingWith(dict["key"]) is perfectly valid.



    A "less dirty" approach might be to use ContainsKey() as a check instead.






    share|improve this answer




















    • 2





      "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

      – Alexander
      7 hours ago


















    3















    There are at least two methods missing from C# dictionaries that in my opinion clean up code considerably in a lot of situations in other languages. The first is returning an Option, which lets you write code like the following in Scala:





    dict.get("key").map(doSomethingWith)


    The second is returning a user-specified default value if the key isn't found:



    doSomethingWith(dict.getOrElse("key", "key not found"))


    There is something to be said for using the idioms a language provides when appropriate, like the Try pattern, but that doesn't mean you have to only use what the language provides. We're programmers. It's okay to create new abstractions to make our specific situation easier to understand, especially if it eliminates a lot of repetition. If you frequently need something, like reverse lookups or iterating through values, make it happen. Create the interface you wish you had.






    share|improve this answer

























    • I like the 2nd option. Maybe I'll have to write an extension method or two :)

      – Adam B
      7 hours ago


















    -3















    IMHO form a purely theoretical point of view, TryGetValue and other ThisAndThat methods is a code smell by itself, it is a method/function that does more than one thing. If methods/functions were composable you would use one to get the value and one to decide what to replace the null with or to handle the exception. The API is flawed in 2019. But it is what it is.



    The currently popular concept of Optional wrappers in every OO language is a more modern but just as flawed solution as it just moves the problem somewhere else.



    There are much better design approaches



    1. Validate the map/dictionary has the keys that are required in another method/function that is a precondition and do it once, and throw an exception that is basically an illegal argument mandatory key is missing with the name of the key so everyone knows exactly how to fix the problem.


    2. Provide a DEFAULT map/dictionary that you copy the values from, then update that with whatever you are putting in there and you always are sure that the keys exist with a proper default and you can just let errors happen because they are indeed exceptional. Or use the DEFAULT map as an overlay map to fill in a sparse one with required keys with the proper default values.


    The goal is to just avoid that TryGetValue mess, it is a code smell because it does more than one thing at time.






    share|improve this answer





























      Your Answer








      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "131"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: false,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f396567%2fare-c-dictionaries-an-anti-pattern%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown




















      StackExchange.ready(function ()
      $("#show-editor-button input, #show-editor-button button").click(function ()
      var showEditor = function()
      $("#show-editor-button").addClass("d-none");
      $("#post-form").removeClass("d-none");
      StackExchange.editor.finallyInit();
      ;

      var useFancy = $(this).data('confirm-use-fancy');
      if(useFancy == 'True')
      var popupTitle = $(this).data('confirm-fancy-title');
      var popupBody = $(this).data('confirm-fancy-body');
      var popupAccept = $(this).data('confirm-fancy-accept-button');

      $(this).loadPopup(
      url: '/post/self-answer-popup',
      loaded: function(popup)
      var pTitle = $(popup).find('h2');
      var pBody = $(popup).find('.popup-body');
      var pSubmit = $(popup).find('.popup-submit');

      pTitle.text(popupTitle);
      pBody.html(popupBody);
      pSubmit.val(popupAccept).click(showEditor);

      )
      else
      var confirmText = $(this).data('confirm-text');
      if (confirmText ? confirm(confirmText) : true)
      showEditor();


      );
      );






      6 Answers
      6






      active

      oldest

      votes








      6 Answers
      6






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      8















      Dictionaries (C# or otherwise) are simply a container where you look up a value based on a key. In many languages it's more correctly identified as a Map with the most common implementation being a HashMap.



      The problem to consider is what happens when a key does not exist. Some languages behave by returning null or nil or some other equivalent value. Silently defaulting to a value instead of informing you that a value does not exist.



      For better or for worse, the C# library designers came up with an idiom to deal with the behavior. They reasoned that the default behavior for looking up a value that does not exist is to throw an exception. If you want to avoid exceptions, then you can use the Try variant. It's the same approach they use for parsing strings into integers or date/time objects. Essentially, the impact is like this:



      T count = int.Parse("12T45"); // throws exception

      if (int.TryParse("12T45", out count))

      // Does not throw exception



      And that carried forward to the dictionary, whose indexer delegates to Get(index):



      var myvalue = dict["12345"]; // throws exception
      myvalue = dict.Get("12345"); // throws exception

      if (dict.TryGet("12345", out myvalue))

      // Does not throw exception



      This is simply the way the language is designed.




      Should out variables be discouraged?



      C# isn't the first language to have them, and they have their purpose in specific situations. If you are trying to build a highly concurrent system, then you cannot use out variables at the concurrency boundaries.



      In many ways, if there is an idiom that is espoused by the language and core library providers, I try to adopt those idioms in my APIs. That makes the API feel more consistent and at home in that language. So a method written in Ruby isn't going to look like a method written in C#, C, or Python. They each have a preferred way of building code, and working with that helps the users of your API learn it more quickly.




      Are Maps in General an Anti-pattern?



      They have their purpose, but many times they may be the wrong solution for the purpose you have. Particularly if you have a bi-directional mapping you need. There are many containers and ways of organizing data. There are many approaches that you can use, and sometimes you need to think a bit before you pick that container.



      If you have a very short list of bi-directional mapping values, then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping.



      Think of the problem domain, and pick the most appropriate tool for the job. If there isn't one, then create it.






      share|improve this answer

























      • "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

        – Blrfl
        3 hours ago











      • If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

        – Berin Loritsch
        3 hours ago











      • It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

        – Blrfl
        1 hour ago















      8















      Dictionaries (C# or otherwise) are simply a container where you look up a value based on a key. In many languages it's more correctly identified as a Map with the most common implementation being a HashMap.



      The problem to consider is what happens when a key does not exist. Some languages behave by returning null or nil or some other equivalent value. Silently defaulting to a value instead of informing you that a value does not exist.



      For better or for worse, the C# library designers came up with an idiom to deal with the behavior. They reasoned that the default behavior for looking up a value that does not exist is to throw an exception. If you want to avoid exceptions, then you can use the Try variant. It's the same approach they use for parsing strings into integers or date/time objects. Essentially, the impact is like this:



      T count = int.Parse("12T45"); // throws exception

      if (int.TryParse("12T45", out count))

      // Does not throw exception



      And that carried forward to the dictionary, whose indexer delegates to Get(index):



      var myvalue = dict["12345"]; // throws exception
      myvalue = dict.Get("12345"); // throws exception

      if (dict.TryGet("12345", out myvalue))

      // Does not throw exception



      This is simply the way the language is designed.




      Should out variables be discouraged?



      C# isn't the first language to have them, and they have their purpose in specific situations. If you are trying to build a highly concurrent system, then you cannot use out variables at the concurrency boundaries.



      In many ways, if there is an idiom that is espoused by the language and core library providers, I try to adopt those idioms in my APIs. That makes the API feel more consistent and at home in that language. So a method written in Ruby isn't going to look like a method written in C#, C, or Python. They each have a preferred way of building code, and working with that helps the users of your API learn it more quickly.




      Are Maps in General an Anti-pattern?



      They have their purpose, but many times they may be the wrong solution for the purpose you have. Particularly if you have a bi-directional mapping you need. There are many containers and ways of organizing data. There are many approaches that you can use, and sometimes you need to think a bit before you pick that container.



      If you have a very short list of bi-directional mapping values, then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping.



      Think of the problem domain, and pick the most appropriate tool for the job. If there isn't one, then create it.






      share|improve this answer

























      • "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

        – Blrfl
        3 hours ago











      • If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

        – Berin Loritsch
        3 hours ago











      • It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

        – Blrfl
        1 hour ago













      8














      8










      8









      Dictionaries (C# or otherwise) are simply a container where you look up a value based on a key. In many languages it's more correctly identified as a Map with the most common implementation being a HashMap.



      The problem to consider is what happens when a key does not exist. Some languages behave by returning null or nil or some other equivalent value. Silently defaulting to a value instead of informing you that a value does not exist.



      For better or for worse, the C# library designers came up with an idiom to deal with the behavior. They reasoned that the default behavior for looking up a value that does not exist is to throw an exception. If you want to avoid exceptions, then you can use the Try variant. It's the same approach they use for parsing strings into integers or date/time objects. Essentially, the impact is like this:



      T count = int.Parse("12T45"); // throws exception

      if (int.TryParse("12T45", out count))

      // Does not throw exception



      And that carried forward to the dictionary, whose indexer delegates to Get(index):



      var myvalue = dict["12345"]; // throws exception
      myvalue = dict.Get("12345"); // throws exception

      if (dict.TryGet("12345", out myvalue))

      // Does not throw exception



      This is simply the way the language is designed.




      Should out variables be discouraged?



      C# isn't the first language to have them, and they have their purpose in specific situations. If you are trying to build a highly concurrent system, then you cannot use out variables at the concurrency boundaries.



      In many ways, if there is an idiom that is espoused by the language and core library providers, I try to adopt those idioms in my APIs. That makes the API feel more consistent and at home in that language. So a method written in Ruby isn't going to look like a method written in C#, C, or Python. They each have a preferred way of building code, and working with that helps the users of your API learn it more quickly.




      Are Maps in General an Anti-pattern?



      They have their purpose, but many times they may be the wrong solution for the purpose you have. Particularly if you have a bi-directional mapping you need. There are many containers and ways of organizing data. There are many approaches that you can use, and sometimes you need to think a bit before you pick that container.



      If you have a very short list of bi-directional mapping values, then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping.



      Think of the problem domain, and pick the most appropriate tool for the job. If there isn't one, then create it.






      share|improve this answer













      Dictionaries (C# or otherwise) are simply a container where you look up a value based on a key. In many languages it's more correctly identified as a Map with the most common implementation being a HashMap.



      The problem to consider is what happens when a key does not exist. Some languages behave by returning null or nil or some other equivalent value. Silently defaulting to a value instead of informing you that a value does not exist.



      For better or for worse, the C# library designers came up with an idiom to deal with the behavior. They reasoned that the default behavior for looking up a value that does not exist is to throw an exception. If you want to avoid exceptions, then you can use the Try variant. It's the same approach they use for parsing strings into integers or date/time objects. Essentially, the impact is like this:



      T count = int.Parse("12T45"); // throws exception

      if (int.TryParse("12T45", out count))

      // Does not throw exception



      And that carried forward to the dictionary, whose indexer delegates to Get(index):



      var myvalue = dict["12345"]; // throws exception
      myvalue = dict.Get("12345"); // throws exception

      if (dict.TryGet("12345", out myvalue))

      // Does not throw exception



      This is simply the way the language is designed.




      Should out variables be discouraged?



      C# isn't the first language to have them, and they have their purpose in specific situations. If you are trying to build a highly concurrent system, then you cannot use out variables at the concurrency boundaries.



      In many ways, if there is an idiom that is espoused by the language and core library providers, I try to adopt those idioms in my APIs. That makes the API feel more consistent and at home in that language. So a method written in Ruby isn't going to look like a method written in C#, C, or Python. They each have a preferred way of building code, and working with that helps the users of your API learn it more quickly.




      Are Maps in General an Anti-pattern?



      They have their purpose, but many times they may be the wrong solution for the purpose you have. Particularly if you have a bi-directional mapping you need. There are many containers and ways of organizing data. There are many approaches that you can use, and sometimes you need to think a bit before you pick that container.



      If you have a very short list of bi-directional mapping values, then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping.



      Think of the problem domain, and pick the most appropriate tool for the job. If there isn't one, then create it.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered 8 hours ago









      Berin LoritschBerin Loritsch

      35.7k5 gold badges66 silver badges140 bronze badges




      35.7k5 gold badges66 silver badges140 bronze badges















      • "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

        – Blrfl
        3 hours ago











      • If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

        – Berin Loritsch
        3 hours ago











      • It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

        – Blrfl
        1 hour ago

















      • "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

        – Blrfl
        3 hours ago











      • If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

        – Berin Loritsch
        3 hours ago











      • It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

        – Blrfl
        1 hour ago
















      "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

      – Blrfl
      3 hours ago





      "then you might only need a list of tuples. Or a list of structs, where you can just as easily find the first match on either side of the mapping." -- If there are optimizations for small sets, they should be made in the library, not rubber-stamped into user code.

      – Blrfl
      3 hours ago













      If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

      – Berin Loritsch
      3 hours ago





      If you choose a list of tuples or a dictionary, that is an implementation detail. It's a question of understanding your problem domain and using the right tool for the job. Obviously, a list exists and a dictionary exists. For the common case, dictionary is correct, but maybe for one or two applications you need to use the list.

      – Berin Loritsch
      3 hours ago













      It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

      – Blrfl
      1 hour ago





      It is, but if the behavior is still the same, that determination should be in the library. I've run across containers implementations in other languages that will switch algorithms if told a priori that the number of entries will be small. I agree with your answer, but once this has been figured out, it should be in a library, maybe as a SmallBidirectionalMap.

      – Blrfl
      1 hour ago













      6















      This is neither a code smell nor an anti-pattern, as using TryGet-style functions with an out parameter is idiomatic C#. However, there are 3 options provided in C# to work with a Dictionary, so should you be sure you are using the correct one for your situation. I think I know where the rumor of there being a problem using an out parameter comes from, so I'll handle that at the end.



      What features to use when working with a C# Dictionary:



      1. If you are sure the key will be in the Dictionary, use the Item[TKey] property

      2. If the key should generally be in the Dictionary, but it is bad/rare/problematic that it is not there, you should use Try...Catch so that an error will be raised and then you can try to handle the error gracefully

      3. If you are not sure the key will be in the Dictionary, use TryGet with the out parameter

      To justify this, one need only refer to the documentation for Dictionary TryGetValue, under "Remarks":




      This method combines the functionality of the ContainsKey method and the Item[TKey] property.



      ...



      Use the TryGetValue method if your code frequently attempts to access
      keys that are not in the dictionary. Using this method is more
      efficient than catching the KeyNotFoundException thrown by the
      Item[TKey] property.



      This method approaches an O(1) operation.




      The whole reason TryGetValue exists is to act as a more convenient way to use ContainsKey and Item[TKey], while avoiding having to search the dictionary twice - so pretending it doesn't exist and doing the two things it does manually is a rather awkward choice.



      In practice, I rarely have ever used a raw Dictionary, due to this simple maxim: choose the most generic class/container that gives you the functionality you need. Dictionary was not designed to look up by value rather than by key (for example), so if that is something you want it may make more sense to use an alternate structure. I think I may have used Dictionary one time in the last year-long development project I did, simply because it was rarely the right tool for the job I was trying to do. Dictionary is certainly not the Swiss Army knife of the C# toolbox.



      What's wrong with out parameters?



      CA1021: Avoid out parameters




      Although return values are commonplace and heavily used, the correct
      application of out and ref parameters requires intermediate design and
      coding skills. Library architects who design for a general audience
      should not expect users to master working with out or ref parameters.




      I'm guessing that's where you heard that out parameters were something like an anti-pattern. As with all rules, you should read closer to understand the 'why', and in this case there is even an explicit mention of how the Try pattern does not violate the rule:




      Methods that implement the Try pattern, such as
      System.Int32.TryParse, do not raise this violation.







      share|improve this answer





























        6















        This is neither a code smell nor an anti-pattern, as using TryGet-style functions with an out parameter is idiomatic C#. However, there are 3 options provided in C# to work with a Dictionary, so should you be sure you are using the correct one for your situation. I think I know where the rumor of there being a problem using an out parameter comes from, so I'll handle that at the end.



        What features to use when working with a C# Dictionary:



        1. If you are sure the key will be in the Dictionary, use the Item[TKey] property

        2. If the key should generally be in the Dictionary, but it is bad/rare/problematic that it is not there, you should use Try...Catch so that an error will be raised and then you can try to handle the error gracefully

        3. If you are not sure the key will be in the Dictionary, use TryGet with the out parameter

        To justify this, one need only refer to the documentation for Dictionary TryGetValue, under "Remarks":




        This method combines the functionality of the ContainsKey method and the Item[TKey] property.



        ...



        Use the TryGetValue method if your code frequently attempts to access
        keys that are not in the dictionary. Using this method is more
        efficient than catching the KeyNotFoundException thrown by the
        Item[TKey] property.



        This method approaches an O(1) operation.




        The whole reason TryGetValue exists is to act as a more convenient way to use ContainsKey and Item[TKey], while avoiding having to search the dictionary twice - so pretending it doesn't exist and doing the two things it does manually is a rather awkward choice.



        In practice, I rarely have ever used a raw Dictionary, due to this simple maxim: choose the most generic class/container that gives you the functionality you need. Dictionary was not designed to look up by value rather than by key (for example), so if that is something you want it may make more sense to use an alternate structure. I think I may have used Dictionary one time in the last year-long development project I did, simply because it was rarely the right tool for the job I was trying to do. Dictionary is certainly not the Swiss Army knife of the C# toolbox.



        What's wrong with out parameters?



        CA1021: Avoid out parameters




        Although return values are commonplace and heavily used, the correct
        application of out and ref parameters requires intermediate design and
        coding skills. Library architects who design for a general audience
        should not expect users to master working with out or ref parameters.




        I'm guessing that's where you heard that out parameters were something like an anti-pattern. As with all rules, you should read closer to understand the 'why', and in this case there is even an explicit mention of how the Try pattern does not violate the rule:




        Methods that implement the Try pattern, such as
        System.Int32.TryParse, do not raise this violation.







        share|improve this answer



























          6














          6










          6









          This is neither a code smell nor an anti-pattern, as using TryGet-style functions with an out parameter is idiomatic C#. However, there are 3 options provided in C# to work with a Dictionary, so should you be sure you are using the correct one for your situation. I think I know where the rumor of there being a problem using an out parameter comes from, so I'll handle that at the end.



          What features to use when working with a C# Dictionary:



          1. If you are sure the key will be in the Dictionary, use the Item[TKey] property

          2. If the key should generally be in the Dictionary, but it is bad/rare/problematic that it is not there, you should use Try...Catch so that an error will be raised and then you can try to handle the error gracefully

          3. If you are not sure the key will be in the Dictionary, use TryGet with the out parameter

          To justify this, one need only refer to the documentation for Dictionary TryGetValue, under "Remarks":




          This method combines the functionality of the ContainsKey method and the Item[TKey] property.



          ...



          Use the TryGetValue method if your code frequently attempts to access
          keys that are not in the dictionary. Using this method is more
          efficient than catching the KeyNotFoundException thrown by the
          Item[TKey] property.



          This method approaches an O(1) operation.




          The whole reason TryGetValue exists is to act as a more convenient way to use ContainsKey and Item[TKey], while avoiding having to search the dictionary twice - so pretending it doesn't exist and doing the two things it does manually is a rather awkward choice.



          In practice, I rarely have ever used a raw Dictionary, due to this simple maxim: choose the most generic class/container that gives you the functionality you need. Dictionary was not designed to look up by value rather than by key (for example), so if that is something you want it may make more sense to use an alternate structure. I think I may have used Dictionary one time in the last year-long development project I did, simply because it was rarely the right tool for the job I was trying to do. Dictionary is certainly not the Swiss Army knife of the C# toolbox.



          What's wrong with out parameters?



          CA1021: Avoid out parameters




          Although return values are commonplace and heavily used, the correct
          application of out and ref parameters requires intermediate design and
          coding skills. Library architects who design for a general audience
          should not expect users to master working with out or ref parameters.




          I'm guessing that's where you heard that out parameters were something like an anti-pattern. As with all rules, you should read closer to understand the 'why', and in this case there is even an explicit mention of how the Try pattern does not violate the rule:




          Methods that implement the Try pattern, such as
          System.Int32.TryParse, do not raise this violation.







          share|improve this answer













          This is neither a code smell nor an anti-pattern, as using TryGet-style functions with an out parameter is idiomatic C#. However, there are 3 options provided in C# to work with a Dictionary, so should you be sure you are using the correct one for your situation. I think I know where the rumor of there being a problem using an out parameter comes from, so I'll handle that at the end.



          What features to use when working with a C# Dictionary:



          1. If you are sure the key will be in the Dictionary, use the Item[TKey] property

          2. If the key should generally be in the Dictionary, but it is bad/rare/problematic that it is not there, you should use Try...Catch so that an error will be raised and then you can try to handle the error gracefully

          3. If you are not sure the key will be in the Dictionary, use TryGet with the out parameter

          To justify this, one need only refer to the documentation for Dictionary TryGetValue, under "Remarks":




          This method combines the functionality of the ContainsKey method and the Item[TKey] property.



          ...



          Use the TryGetValue method if your code frequently attempts to access
          keys that are not in the dictionary. Using this method is more
          efficient than catching the KeyNotFoundException thrown by the
          Item[TKey] property.



          This method approaches an O(1) operation.




          The whole reason TryGetValue exists is to act as a more convenient way to use ContainsKey and Item[TKey], while avoiding having to search the dictionary twice - so pretending it doesn't exist and doing the two things it does manually is a rather awkward choice.



          In practice, I rarely have ever used a raw Dictionary, due to this simple maxim: choose the most generic class/container that gives you the functionality you need. Dictionary was not designed to look up by value rather than by key (for example), so if that is something you want it may make more sense to use an alternate structure. I think I may have used Dictionary one time in the last year-long development project I did, simply because it was rarely the right tool for the job I was trying to do. Dictionary is certainly not the Swiss Army knife of the C# toolbox.



          What's wrong with out parameters?



          CA1021: Avoid out parameters




          Although return values are commonplace and heavily used, the correct
          application of out and ref parameters requires intermediate design and
          coding skills. Library architects who design for a general audience
          should not expect users to master working with out or ref parameters.




          I'm guessing that's where you heard that out parameters were something like an anti-pattern. As with all rules, you should read closer to understand the 'why', and in this case there is even an explicit mention of how the Try pattern does not violate the rule:




          Methods that implement the Try pattern, such as
          System.Int32.TryParse, do not raise this violation.








          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 7 hours ago









          BrianHBrianH

          5,7281 gold badge17 silver badges22 bronze badges




          5,7281 gold badge17 silver badges22 bronze badges
























              4















              Some good answers here on the general principles of hashtables/dictionaries. But I thought I'd touch on your code example,



              int x;
              if (dict.TryGetValue("key", out x)

              DoSomethingWith(x);



              As of C# 7 (which I think is around two years old), that can be simplified to:



              if (dict.TryGetValue("key", out var x) 

              DoSomethingWith(x);



              And of course it could be reduced to one line:



              if (dict.TryGetValue("key", out var x) DoSomethingWith(x);


              If you have a default value for when the key doesn't exist, it can become:



              DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);


              So you can achieve compact forms by using reasonably recent language additions.






              share|improve this answer




















              • 1





                Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

                – BrianH
                34 mins ago
















              4















              Some good answers here on the general principles of hashtables/dictionaries. But I thought I'd touch on your code example,



              int x;
              if (dict.TryGetValue("key", out x)

              DoSomethingWith(x);



              As of C# 7 (which I think is around two years old), that can be simplified to:



              if (dict.TryGetValue("key", out var x) 

              DoSomethingWith(x);



              And of course it could be reduced to one line:



              if (dict.TryGetValue("key", out var x) DoSomethingWith(x);


              If you have a default value for when the key doesn't exist, it can become:



              DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);


              So you can achieve compact forms by using reasonably recent language additions.






              share|improve this answer




















              • 1





                Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

                – BrianH
                34 mins ago














              4














              4










              4









              Some good answers here on the general principles of hashtables/dictionaries. But I thought I'd touch on your code example,



              int x;
              if (dict.TryGetValue("key", out x)

              DoSomethingWith(x);



              As of C# 7 (which I think is around two years old), that can be simplified to:



              if (dict.TryGetValue("key", out var x) 

              DoSomethingWith(x);



              And of course it could be reduced to one line:



              if (dict.TryGetValue("key", out var x) DoSomethingWith(x);


              If you have a default value for when the key doesn't exist, it can become:



              DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);


              So you can achieve compact forms by using reasonably recent language additions.






              share|improve this answer













              Some good answers here on the general principles of hashtables/dictionaries. But I thought I'd touch on your code example,



              int x;
              if (dict.TryGetValue("key", out x)

              DoSomethingWith(x);



              As of C# 7 (which I think is around two years old), that can be simplified to:



              if (dict.TryGetValue("key", out var x) 

              DoSomethingWith(x);



              And of course it could be reduced to one line:



              if (dict.TryGetValue("key", out var x) DoSomethingWith(x);


              If you have a default value for when the key doesn't exist, it can become:



              DoSomethingWith(dict.TryGetValue("key", out var x) ? x : defaultValue);


              So you can achieve compact forms by using reasonably recent language additions.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 4 hours ago









              David ArnoDavid Arno

              31.9k8 gold badges66 silver badges102 bronze badges




              31.9k8 gold badges66 silver badges102 bronze badges










              • 1





                Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

                – BrianH
                34 mins ago













              • 1





                Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

                – BrianH
                34 mins ago








              1




              1





              Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

              – BrianH
              34 mins ago






              Good call on the v7 syntax, nice little option to have to cut out the extra definition line while allowing the use of var +1

              – BrianH
              34 mins ago












              3















              The TryGetValue() construct is only necessary if you don't know whether "key" is present as a key within the dictionary or not, otherwise DoSomethingWith(dict["key"]) is perfectly valid.



              A "less dirty" approach might be to use ContainsKey() as a check instead.






              share|improve this answer




















              • 2





                "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

                – Alexander
                7 hours ago















              3















              The TryGetValue() construct is only necessary if you don't know whether "key" is present as a key within the dictionary or not, otherwise DoSomethingWith(dict["key"]) is perfectly valid.



              A "less dirty" approach might be to use ContainsKey() as a check instead.






              share|improve this answer




















              • 2





                "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

                – Alexander
                7 hours ago













              3














              3










              3









              The TryGetValue() construct is only necessary if you don't know whether "key" is present as a key within the dictionary or not, otherwise DoSomethingWith(dict["key"]) is perfectly valid.



              A "less dirty" approach might be to use ContainsKey() as a check instead.






              share|improve this answer













              The TryGetValue() construct is only necessary if you don't know whether "key" is present as a key within the dictionary or not, otherwise DoSomethingWith(dict["key"]) is perfectly valid.



              A "less dirty" approach might be to use ContainsKey() as a check instead.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 8 hours ago









              PeregrinePeregrine

              1,1441 gold badge6 silver badges9 bronze badges




              1,1441 gold badge6 silver badges9 bronze badges










              • 2





                "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

                – Alexander
                7 hours ago












              • 2





                "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

                – Alexander
                7 hours ago







              2




              2





              "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

              – Alexander
              7 hours ago





              "A "less dirty" approach might be to use ContainsKey() as a check instead." I disagree. As suboptimal as TryGetValue is, at least it makes it hard to forget to handle the empty case. Ideally, I wish this would just return an Optional.

              – Alexander
              7 hours ago











              3















              There are at least two methods missing from C# dictionaries that in my opinion clean up code considerably in a lot of situations in other languages. The first is returning an Option, which lets you write code like the following in Scala:





              dict.get("key").map(doSomethingWith)


              The second is returning a user-specified default value if the key isn't found:



              doSomethingWith(dict.getOrElse("key", "key not found"))


              There is something to be said for using the idioms a language provides when appropriate, like the Try pattern, but that doesn't mean you have to only use what the language provides. We're programmers. It's okay to create new abstractions to make our specific situation easier to understand, especially if it eliminates a lot of repetition. If you frequently need something, like reverse lookups or iterating through values, make it happen. Create the interface you wish you had.






              share|improve this answer

























              • I like the 2nd option. Maybe I'll have to write an extension method or two :)

                – Adam B
                7 hours ago















              3















              There are at least two methods missing from C# dictionaries that in my opinion clean up code considerably in a lot of situations in other languages. The first is returning an Option, which lets you write code like the following in Scala:





              dict.get("key").map(doSomethingWith)


              The second is returning a user-specified default value if the key isn't found:



              doSomethingWith(dict.getOrElse("key", "key not found"))


              There is something to be said for using the idioms a language provides when appropriate, like the Try pattern, but that doesn't mean you have to only use what the language provides. We're programmers. It's okay to create new abstractions to make our specific situation easier to understand, especially if it eliminates a lot of repetition. If you frequently need something, like reverse lookups or iterating through values, make it happen. Create the interface you wish you had.






              share|improve this answer

























              • I like the 2nd option. Maybe I'll have to write an extension method or two :)

                – Adam B
                7 hours ago













              3














              3










              3









              There are at least two methods missing from C# dictionaries that in my opinion clean up code considerably in a lot of situations in other languages. The first is returning an Option, which lets you write code like the following in Scala:





              dict.get("key").map(doSomethingWith)


              The second is returning a user-specified default value if the key isn't found:



              doSomethingWith(dict.getOrElse("key", "key not found"))


              There is something to be said for using the idioms a language provides when appropriate, like the Try pattern, but that doesn't mean you have to only use what the language provides. We're programmers. It's okay to create new abstractions to make our specific situation easier to understand, especially if it eliminates a lot of repetition. If you frequently need something, like reverse lookups or iterating through values, make it happen. Create the interface you wish you had.






              share|improve this answer













              There are at least two methods missing from C# dictionaries that in my opinion clean up code considerably in a lot of situations in other languages. The first is returning an Option, which lets you write code like the following in Scala:





              dict.get("key").map(doSomethingWith)


              The second is returning a user-specified default value if the key isn't found:



              doSomethingWith(dict.getOrElse("key", "key not found"))


              There is something to be said for using the idioms a language provides when appropriate, like the Try pattern, but that doesn't mean you have to only use what the language provides. We're programmers. It's okay to create new abstractions to make our specific situation easier to understand, especially if it eliminates a lot of repetition. If you frequently need something, like reverse lookups or iterating through values, make it happen. Create the interface you wish you had.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 7 hours ago









              Karl BielefeldtKarl Bielefeldt

              124k34 gold badges228 silver badges425 bronze badges




              124k34 gold badges228 silver badges425 bronze badges















              • I like the 2nd option. Maybe I'll have to write an extension method or two :)

                – Adam B
                7 hours ago

















              • I like the 2nd option. Maybe I'll have to write an extension method or two :)

                – Adam B
                7 hours ago
















              I like the 2nd option. Maybe I'll have to write an extension method or two :)

              – Adam B
              7 hours ago





              I like the 2nd option. Maybe I'll have to write an extension method or two :)

              – Adam B
              7 hours ago











              -3















              IMHO form a purely theoretical point of view, TryGetValue and other ThisAndThat methods is a code smell by itself, it is a method/function that does more than one thing. If methods/functions were composable you would use one to get the value and one to decide what to replace the null with or to handle the exception. The API is flawed in 2019. But it is what it is.



              The currently popular concept of Optional wrappers in every OO language is a more modern but just as flawed solution as it just moves the problem somewhere else.



              There are much better design approaches



              1. Validate the map/dictionary has the keys that are required in another method/function that is a precondition and do it once, and throw an exception that is basically an illegal argument mandatory key is missing with the name of the key so everyone knows exactly how to fix the problem.


              2. Provide a DEFAULT map/dictionary that you copy the values from, then update that with whatever you are putting in there and you always are sure that the keys exist with a proper default and you can just let errors happen because they are indeed exceptional. Or use the DEFAULT map as an overlay map to fill in a sparse one with required keys with the proper default values.


              The goal is to just avoid that TryGetValue mess, it is a code smell because it does more than one thing at time.






              share|improve this answer































                -3















                IMHO form a purely theoretical point of view, TryGetValue and other ThisAndThat methods is a code smell by itself, it is a method/function that does more than one thing. If methods/functions were composable you would use one to get the value and one to decide what to replace the null with or to handle the exception. The API is flawed in 2019. But it is what it is.



                The currently popular concept of Optional wrappers in every OO language is a more modern but just as flawed solution as it just moves the problem somewhere else.



                There are much better design approaches



                1. Validate the map/dictionary has the keys that are required in another method/function that is a precondition and do it once, and throw an exception that is basically an illegal argument mandatory key is missing with the name of the key so everyone knows exactly how to fix the problem.


                2. Provide a DEFAULT map/dictionary that you copy the values from, then update that with whatever you are putting in there and you always are sure that the keys exist with a proper default and you can just let errors happen because they are indeed exceptional. Or use the DEFAULT map as an overlay map to fill in a sparse one with required keys with the proper default values.


                The goal is to just avoid that TryGetValue mess, it is a code smell because it does more than one thing at time.






                share|improve this answer





























                  -3














                  -3










                  -3









                  IMHO form a purely theoretical point of view, TryGetValue and other ThisAndThat methods is a code smell by itself, it is a method/function that does more than one thing. If methods/functions were composable you would use one to get the value and one to decide what to replace the null with or to handle the exception. The API is flawed in 2019. But it is what it is.



                  The currently popular concept of Optional wrappers in every OO language is a more modern but just as flawed solution as it just moves the problem somewhere else.



                  There are much better design approaches



                  1. Validate the map/dictionary has the keys that are required in another method/function that is a precondition and do it once, and throw an exception that is basically an illegal argument mandatory key is missing with the name of the key so everyone knows exactly how to fix the problem.


                  2. Provide a DEFAULT map/dictionary that you copy the values from, then update that with whatever you are putting in there and you always are sure that the keys exist with a proper default and you can just let errors happen because they are indeed exceptional. Or use the DEFAULT map as an overlay map to fill in a sparse one with required keys with the proper default values.


                  The goal is to just avoid that TryGetValue mess, it is a code smell because it does more than one thing at time.






                  share|improve this answer















                  IMHO form a purely theoretical point of view, TryGetValue and other ThisAndThat methods is a code smell by itself, it is a method/function that does more than one thing. If methods/functions were composable you would use one to get the value and one to decide what to replace the null with or to handle the exception. The API is flawed in 2019. But it is what it is.



                  The currently popular concept of Optional wrappers in every OO language is a more modern but just as flawed solution as it just moves the problem somewhere else.



                  There are much better design approaches



                  1. Validate the map/dictionary has the keys that are required in another method/function that is a precondition and do it once, and throw an exception that is basically an illegal argument mandatory key is missing with the name of the key so everyone knows exactly how to fix the problem.


                  2. Provide a DEFAULT map/dictionary that you copy the values from, then update that with whatever you are putting in there and you always are sure that the keys exist with a proper default and you can just let errors happen because they are indeed exceptional. Or use the DEFAULT map as an overlay map to fill in a sparse one with required keys with the proper default values.


                  The goal is to just avoid that TryGetValue mess, it is a code smell because it does more than one thing at time.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 5 hours ago

























                  answered 6 hours ago









                  Jarrod RobersonJarrod Roberson

                  20.3k6 gold badges46 silver badges82 bronze badges




                  20.3k6 gold badges46 silver badges82 bronze badges






























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Software Engineering Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsoftwareengineering.stackexchange.com%2fquestions%2f396567%2fare-c-dictionaries-an-anti-pattern%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown











                      Popular posts from this blog

                      Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                      Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                      Ласкавець круглолистий Зміст Опис | Поширення | Галерея | Примітки | Посилання | Навігаційне меню58171138361-22960890446Bupleurum rotundifoliumEuro+Med PlantbasePlants of the World Online — Kew ScienceGermplasm Resources Information Network (GRIN)Ласкавецькн. VI : Літери Ком — Левиправивши або дописавши її