public static object InvokeUnaryOperator(string operatorName, object operand)
{
Type operandType = operand.GetType();
TypeCode operandTypeCode = Type.GetTypeCode(operandType);
if (IsNumeric(operandTypeCode))
{
// HACK: optimization to get to the correct operators faster
// is it worthy?
switch (((int)operatorName[3] << 8) + (int)operatorName[operatorName.Length - 1])
{
case ((int)'U' << 8) + (int)'n': // op_UnaryNegation
return op_UnaryNegation(operand, operandTypeCode);
default:
throw new ArgumentException(operatorName + " " + operand);
}
}
else
{
var args = new[] { operand };
var duck = operand as IQuackFu;
if (duck != null)
return duck.QuackInvoke(operatorName, args);
try
{
return Invoke(operandType, operatorName, args);
}
catch (MissingMethodException)
{
try
{
return InvokeRuntimeServicesOperator(operatorName, args);
}
catch (MissingMethodException)
{
}
throw; // always throw the original exception
}
}
}