You have mistaken, double quotes "$b" does not prevent parameter expansion, it prevents pathname expansion (aka globbing) and fields splitting.
If you want to prevent parameter expansion, you need to use quoting, like single quote '$b' or escaping \$b:
$ echo '$b'
or:
$ echo \$b
then $b is output literalliterally.
In the example, there's nothing to prevent parameter expansion.
When the shell read the input c=$(b=2; echo $b), it performperforms token recognition, saw that $( is the token for command substitution. So it treats the rest of string between $( and ) to be interpreted in the subshell created by command substitution, not the current shell.