You can possibly do it with \verb. But let's look what happens with your attempt. In
\newcommand{\mon}[1]{%
\mbox{%
\texttt{%
\protect\detokenize{#1}%
}%
}%
}
there is a misplaced \protect that however does nothing bad. The problem is that TeX sees #6 before the “detokenization” actually takes place and this results in a bad token list to be passed as argument to \texttt. Indeed, if you use \ttfamily the problem is solved:
\newcommand{\mon}[1]{%
\mbox{%
\ttfamily
\detokenize{#1}%
}%
}
A different strategy could be performing \detokenize before doing anything else:
\newcommand{\mon}[1]{%
\expandafter\monAUX\expandafter{\detokenize{#1}}%
}
\newcommand{\monAUX}[1]{%
\mbox{\texttt{#1}}%
}
This however doesn't solve the problem with F#, because you'll clearly see the # is doubled. That's part of how \detokenize works (and TeX is designed), so for this particular application I'm afraid \verb is the solution. Or some less heavy trick that changes the category code of # (so it can't be used in the argument to another command).
A different approach might be with expl3:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_const:Nx \c_ledfan_doublehash_tl { \tl_to_str:n { # } }
\tl_new:N \l_ledfan_mon_tl
\NewDocumentCommand{\mon}{m}
{
\tl_set:Nf \l_ledfan_mon_tl { \tl_to_str:n { #1 } }
\tl_replace_all:NVV \l_ledfan_mon_tl \c_ledfan_doublehash_tl \c_hash_str
\texttt{ \tl_use:N \l_ledfan_mon_tl }
}
\cs_generate_variant:Nn \tl_replace_all:Nnn { NVV }
\ExplSyntaxOff
\begin{document}
\mon{F#}
\mon{C##}
\end{document}
The assumption is that any ## in the token list we build comes from \tl_to_str:n (which is \detokenize in disguise) applied to a #6 token, so it's replaced by a single one.

This has still some limitations, because it can't go in the argument of any argument that performs some \protected@edef or \protected@write; for instance \textbf and similar commands or \section, \caption and friends.
\verb|F#|– egreg Jan 24 '16 at 08:47