Why is escaped # breaking my command?

You can't generally use \# in a label, because it doesn't expand to a character. However, in this particular situation a workaround is possible:

\documentclass{article}
\usepackage{hyperref}

\newcommand{\termExplanation}[1]{%
  \item[#1]%
  \begingroup
  % locally disable \#
  \def\#{?hashmark?}%
  \phantomsection\label{#1}%
  \endgroup
}
\newcommand{\newTerm}[1]{%
  \begingroup
  % locally disable \#
  \def\#{?hashmark?}%
  \edef\x{\endgroup\noexpand\hyperref[#1]}\x{\emph{#1}}%
}


\begin{document}
\begin{description}
\termExplanation{C\#} Hello, World!
\termExplanation{lorem} Lorem Ipsum!
\end{description}

\newTerm{C\#} \newTerm{lorem}
\end{document}

The trick is to tell LaTeX that \# in a label writes ?hashmark?; the same trick is used to retrieve the label before \hyperref does its job.

Don't forget \phantomsection that creates a suitable anchor.

enter image description here


The problem is that the content of \label doesn't handle these special characters well. The easiest alternative would be to simply not use the special characters and define variants of your commands that allow an arbitrary label in such case:

\documentclass{article}
\usepackage{hyperref}

\makeatletter
\def\termExplanation{%
  \@ifnextchar[{\termExplanation@opt}{\termExplanation@noopt}
}
\def\termExplanation@opt[#1]#2{%
  \item[#2]\label{#1}%
}
\def\termExplanation@noopt#1{\termExplanation@opt[#1]{#1}}

\def\newTerm{%
  \@ifnextchar[{\newTerm@opt}{\newTerm@noopt}%
}
\def\newTerm@opt[#1]#2{%
  \hyperref[#1]{\emph{#2}}%
}
\def\newTerm@noopt#1{\newTerm@opt[#1]{#1}}
\makeatother

\begin{document}
\begin{description}
\termExplanation[chash]{C\#} Hello, World!
\termExplanation{lorem} Lorem Ipsum!
\end{description}

\newTerm[chash]{C\#} \newTerm{lorem}
\end{document}

To understand what this bit of code those, I recommend you have a look at:

  • What do \makeatletter and \makeatother do?
  • Understanding \@ifnextchar

as they provide very comprehensive answers. Otherwise, the \def command is the TeX primitive behind \newcommand and offers a little more flexibility in the way arguments can be given, though definitely in most cases use \newcommand.

A better option alternative, as suggested by egreg in the comments, is:

\makeatletter
\newcommand\termExplanation{\@dblarg\termExplanation@opt}
\def\termExplanation@opt[#1]#2{\item[#2]\label{#1}}
\newcommand\newTerm{\@dblarg\newTerm@opt}
\def\newTerm@opt[#1]#2{\hyperref[#1]{\emph{#2}}}
\makeatother

As a last note, it really seems to me like you are creating a glossary. If so, then you should also have a look at the glossaries package. I provide a small MWE of the glossaries package below:

Main file:

\documentclass{article}

\usepackage{hyperref}
\usepackage[toc]{glossaries}

\renewcommand*{\glstextformat}[1]{\emph{#1}}
\loadglsentries{glossary}

\makeglossaries

\begin{document}

You can now refer to glossary terms with \gls{permittivity} and
\gls{permeability}.  You can even get the plural with \glspl{permittivity} and
get the capitalized version with \Gls{permittivity} and \Glspl{permeability}.

\clearpage
\printglossaries

\end{document}

and glossary.tex:

\newglossaryentry{permeability}{
    name={permeability},
    plural={permeabilities},
    symbol={\(\mu\)},
    parent={},
    description={A measure of how easy it is to form a magnetic field in a medium.}
}

\newglossaryentry{permittivity}{
    name={permittivity},
    plural={permittivities},
    symbol={\(\varepsilon\)},
    parent={},
    description={A measure of the resistance encountered when forming an electric field in a medium}
}

and the output:

output1 output2

Note that the glossaries package requires an additional run of makeglossaries in order to process the glossary entries.