How to handle a KeyNotFoundException?

1

I have a question, I tried to find some content in Google but I did not find it.

I have a block try catch as follows:

try
{
    //código
    string idFormaPgto = Dictionaries.FormaPgto[_order.FK_PEDIDOS_FORMA_PAGAMENTO];
    //restante do código
}
catch(Exception e)
{

}

The problem is that sometimes I will get a KeyNotFoundException but the following code MUST continue and I need to set a default vallor for idFormaPgto , I do not know if there is a more elegant and correct way of treating this, what I thought was:

try
{
    //código
    string idFormaPgto = "";
    try
    {
       idFormaPgto = Dictionaries.FormaPgto[_order.FK_PEDIDOS_FORMA_PAGAMENTO];
    }
    catch(Exception e)
    {
       idFormaPgto = "1"; //tratamento do idFormaPgto 
    }
    //restante do código
}
catch(Exception e)
{

}

My code solves the problem, but I believe that is not the most correct way to do this, perhaps by using some method of extending the class Dictionary but I do not know any. The goal is to treat this KeyNotFoundException without using try catch within try catch

    
asked by anonymous 08.08.2018 / 14:43

3 answers

5

You can simply use the TryGetValue method. This method tries to get the value for the indicated key and, if the key does not exist, returns the default of the type.

string idFormaPgto;
Dictionaries.FormaPgto.TryGetValue[_order.FK_PEDIDOS_FORMA_PAGAMENTO, out idFormaPgto];

If you want to shorten a little more idea and make it look more like the FirstOrDefault method of LINQ, you can write an extension method for dictionaries.

For example:

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var dicio = new Dictionary<int, string>
        {
            { 65, "A" },
            { 74, "J" },
            { 69, "E" }
        };

        Console.WriteLine(dicio.GetByKeyOrDefault(65) ?? "Chave inexistente");
        Console.WriteLine(dicio.GetByKeyOrDefault(80) ?? "Chave inexistente");
        Console.WriteLine(dicio.GetByKeyOrDefault(69) ?? "Chave inexistente");
    }
}

public static class DictionaryExtensions
{
    public static TValue GetByKeyOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key)
        => dict.ContainsKey(key) ? dict[key] : default(TValue); 
}

See working in .NET Fiddle

Note that in the method implementation, GetByKeyOrDefault , you can still do a micro-optimization and use the TryGetValue method so you do not need to do two queries in the dictionary (one in ContainsKey and another when getting the value).

    
08.08.2018 / 15:01
3

You can simply use Linq , as in the example below:

var dicionario= new Dictionary<string, string> {
    { "teste 1", "1" },
    { "testando", "2" },
};

var idFormaPgto = dicionario.SingleOrDefault(x=> x.Key.Equals(_order.FK_PEDIDOS_FORMA_PAGAMENTO)).Value ?? "1";

Edit As argued in the comments this is a basic approach and should only be considered in a timely application. It is important to pay attention to the comments pointed out by

  

Linq:   That way you lose all the idea of using a dictionary. The method   SingleOrDefault will get an enumerator, move it item by item and make the   validation of each of them. You simply throw away the main   reason for a dictionary that is having search complexity O (1) and becomes   have search complexity O (N)

    
08.08.2018 / 15:03
1

You can use the ContainsKey method, where you pass the key you are looking for and will be returned whether or not it exists in your Dictionary < strong>.

string idFormaPgto = "1";

//Se a key existir no seu Dictionary nós iremos pegar o valor, senão iremos manter o valor 1
if (Dictionaries.ContainsKey[_order.FK_PEDIDOS_FORMA_PAGAMENTO])
      idFormaPgto = Dictionaries[_order.FK_PEDIDOS_FORMA_PAGAMENTO];

If you want to do with a ternary condition it would look like this:

    string idFormaPgto = Dictionaries.ContainsKey[_order.FK_PEDIDOS_FORMA_PAGAMENTO] ? Dictionaries[_order.FK_PEDIDOS_FORMA_PAGAMENTO] : "1";
    
08.08.2018 / 14:52