Letter Combinations of a phone number using a Dictionary
Review


LetterCombinations returns an IList&lt;string&gt; but I see no reason to return a modifiable collection. Consider returning IEnumerable&lt;string&gt; instead.
A method's name should be a verb. Change LetterCombinations to GetLetterCombinations, FindLetterCombinations or PermutateLetterCombinations.
You did good by creating a private function that performs the recursion with intermediate parameters. This way, the user of this API only needs to think about the public endpoint. However, it could have used the same name as the public method. An overload would not resulted in a conflict. The postfix *Function is weird.
Prefer the use of var if the type can be read from code: var lettersMap = new Dictionary&lt;char, char[]&gt;();
You are looking to get familiar with LINQ, however the next statement did not require the LINQ wrapper Count() of a string's Length property: if (sb.Length == digits.Count()).
Use more consistent indentation for your class members.
Having the opening curly brace on the same line is ok, but it's more a convention in Java than in C#, where the opening curly brace is usually on the next line.
See Jesse C. Slicer's answer to move the static data out of the method.




Peculiarities

Did you plan to return the empty result list or throw an exception on this edge case?


if (String.IsNullOrEmpty(digits)){
    return result;
    throw new ArgumentNullException(nameof(digits));
}



The next line is followed by a loop over values but doesn't care whether the operation succeeded:


lettersMap.TryGetValue(digits[pos], out char[] values);



Did you plan to write this instead?

if (lettersMap.TryGetValue(digits[pos], out char[] values)) 
{
    // ..
}


You are using both char and Char in the next line. Is there a specific reason to use both these types?


Dictionary&lt;Char, Char[]&gt; lettersMap = new Dictionary&lt;Char, char[]&gt;();