There is a lot of confusion and partial or plain wrong answers.
$0 is argv[0], the command given to start whatever shell or script you are currently running. The login process creates $0 (it becomes -bash for example). During login the getty code may define $SHELL (which is not always available in every type of shell).
That means when you first logon (using the above examples) $0 and $SHELL will match, sort of. When executing the script pandeesh wrote to test methods, running the script changed $0 for the duration of the script. Therefore, $0 is not reliable except when you are running in the login shell.
The SHELL variable is not changed by executing the shebang; exec looks up the magic word, like #!/bin/csh, from the first line of the script and executes the shell it points to
in order to run the script.
Next, /bin/sh is a special case. First off /bin is guaranteed to be available right when the system boots. So all boot up code depends on being able to run some shell. The shell is not specified by any standard, so /bin/sh has to be a symlink link or something called a POSIX-compliant shell. In the case of Solaris, /bin/sh is a POSIX-compliant Bourne shell. In Linux it is often a symlink to bash. Linux is not UNIX BTW. So /bin/sh may not always be POSIX-compliant.
Finally, as methyl said in another post to pandeesh - there is no one guaranteed single way to determine the shell, once it is running, in spite of all of the answers given above.
But. Best practices in shell scripting says: 'Always put a shebang at the top of the script, except in the case of a script meant to be sourced, ex: .profile'. Doing this solves most of the mysteries.
Any production environment that used all of the shells pandeesh looked for would be completely unmaintainable. Some shells like csh, should be avoided in spite of some deluded academic types who insist on teaching it.
Please stop posting more guaranteed ways to get the shell. There are none, just hacks that work sometimes, sometimes not.