\def vs. \define
There are a lot of ways to define commands in ConTeXt. One of them is the good old \def primitive. The syntax is nicely described in the TeXbook:
Now that we have seen a number of examples, let's look at the
precise rules that govern TeX macros. Definitions have the general form
\def〈control sequence〉〈parameter text〉{〈replacement text〉}
where the 〈parameter text〉 contains no braces, and where all occurrences
of { and } in the 〈replacement text〉 are properly nested. Furthermore
the # symbol has a special significance: In the 〈parameter text〉, the
first appearance of # must be followed by 1, the next by 2, and
so on; up to nine #'s are allowed. In the 〈replacement text〉 each #
must be followed by a digit that appeared after # in the 〈parameter text〉,
or else the # should be followed by another #. The latter case stands
for a single # token when the macro is expanded; the former case stands
for insertion of the corresponding argument. – The TeXbook, page 203.
Because it might be tedious to write things like #1#2#3#4#5 by hand if you have many arguments, ConTeXt defines a thin wrapper around \def, called \define (similar to LaTeX's \newcommand, but no support for optional arguments). The syntax is
\define[〈number of parameters〉]〈control sequence〉{〈replacement text〉}
where the 〈number of parameters〉 is optional in case it is zero. In contrast to \def, the \define macro also defines the 〈control sequence〉 as protected and emits a warning in the log, if the 〈control sequence〉 has already been defined.
Valid names
Both \def and \define have something in common and that is that the 〈control sequence〉 has to begin with an escape character (usually \) and only contain characters of category code 11 (letters) or is an active character.
The problem with \define is that it forwards whatever you give as 〈control sequence〉 directly to \def and you might end up with a different 〈parameter text〉 than you intended.
Let's take a look at your definitions:
\define[0]{\My-hello}{Hello!} becomes \unexpanded\def\My-hello{Hello!} so in this case 〈control sequence〉=\My and 〈parameter text〉=-hello because - has character code 12 (other) and cannot be part of a 〈control sequence〉.
As you proceed to \define[0]{\My-hello-2}{Hello!} this is turned into \unexpanded\def\My-hello-2{Hello!} again. However, \define first checks whether 〈control sequence〉 is already defined and because 〈control sequence〉=\My again, you end up with a message
system > command '\My-hello-2' is already defined
in the log file. The same thing holds for \define[0]{\My_hello_3}{Hello!}.
The last instance \define[0]{\_My_hello}{Hello!} is a tricky case. Above I actually lied to you when I said that a 〈control sequence〉 can only contain characters with catcode 11. There is an exception and that is when 〈control sequence〉 is a single character. The underscore has catcode 12 in ConTeXt and therefore this definition becomes \unexpanded\def\_My_hello{Hello!} where 〈control sequence〉=\_ and 〈parameter text〉=My_hello. Unfortunately, \_ is already defined (to typeset an underscore) and therefore you get the log message
system > command '\_My_hello' is already defined
What to do about this?
As you see it becomes quite peculiar when you want to have any special characters as part of a 〈control sequence〉. Luckily, there is a way out. TeX comes with a pair of primitives \csname...\endcsname which allows you to use characters which don't have catcode 11 as a name. Again ConTeXt comes with a handy wrapper around this:
\setvalue{My-hello}{Hello!}
\setvalue{My-hello-2}{Hello!}
\setvalue{My_hello_3}{Hello!}
\setvalue{_My_hello}{Hello!}
If you want to get the 〈replacement text〉 that you stored earlier, the you can use \getvalue.
\getvalue{My-hello}
\getvalue{My-hello-2}
\getvalue{My_hello_3}
\getvalue{_My_hello}
\unexpanded\defin TeX. Is your question about a\unprotected context? Btw: For using best practices you will have to be a bit more specific about the kind of command you are trying to define, see the last sentences of this entry on the wiki. – TeXnician Feb 12 '19 at 14:34\unprotect! What is the difference between\defand\define? – Violapterin Feb 12 '19 at 17:41\unprotectwill not make this work because-still has catcode 12. – Henri Menke Feb 12 '19 at 20:37