Não há diferença nos conjuntos compilados quando você compila com um sinalizador versus outro. Os nomes "Debug" e "Release" são puramente convencionais. A configuração que eu suponho que você está preocupado é se o código está otimizado ou não. Isso também não é detectável.
Em vez disso, como sugerido pelo @HABO, a resposta seria definir um sinalizador, presente nas máquinas do desenvolvedor, o que torna o código de depuração aceitável. Você poderia usar algo tão simples como o seguinte:
static class AssertProductionOptimized
{
private static bool checkCompleted = false;
private static bool isDeveloper = false;
private const string regPath = @"Software\My Awesome Software, Inc";
private const string regValue = "IsDeveloper";
[Conditional("DEBUG")]
public static void AssertOptimized()
{
if (checkCompleted)
{
isDeveloper = checkIfDeveloper();
checkCompleted = true;
}
if (!isDeveloper)
{
throw new InvalidOperationException(string.Format("Debug code running "
+ "on non-developer machine. Either build without DEBUG flag, or "
+ "add a DWORD named {1} with a value of 1 to HKLM\{0}",
regPath, regValue));
}
}
private static void checkIfDeveloper()
{
RegistryKey hkKey = null;
try
{
hkKey = Registry.LocalMachine.OpenSubKey(regPath);
// if the key does not exist, we are not a developer
if (hkKey == null)
return false;
var hkValueObj = hkKey.GetValue(regValue);
return object.Equals(hkValueObj, 1);
}
catch (Exception ex)
{
throw new Exception("Exception occurred while checking developer status", ex);
}
finally
{
if (hkKey != null)
hkKey.Dispose();
}
}
}