Quick disclaimer: I realize a similar question has already been asked here How to get defined operators for a type in .net, but since this question does not answer the question asked here as this question expands upon the one mentioned above, an answer to this question would be appreciated.
I would like to obtain a list of all operators that can de applied to a type. To simplify the code snippets, I will only print the operators in the console though.
For example, DateTime defines a +, two - operators, and one operator for each inequality <, <=, etc. and the == operators. I can get a comprehensive list of all these operators by using the following code:
foreach (var method in typeof(DateTime).GetMethods())
{
if (method.IsSpecialName)
{
Console.WriteLine(method.Name);
}
}
which prints:
get_UtcNow
op_Addition
op_Subtraction
op_Subtraction
op_Equality
op_Inequality
op_LessThan
op_LessThanOrEqual
op_GreaterThan
op_GreaterThanOrEqual
get_Date
...
where every method beginning with op_ is the corresponding operator.
However when applying this code to int or any other primitive type, the list is either incomprehensive or even empty.
When applied to typeof(int) for example, there are no methods with special name and as such no operators, which is obviously wrong.
I think this is because DateTime uses operator overloading while int does not and as such does not define the methods 'op_Addition', etc. The - operator for example on int can be pretty much directly translated to the sub instruction in assembly.
If I wanted to get all operators for int anyways now, I could obviously just define a list of all operators defined on int and any other type, but since there are quite a few types, for which you cannot get all operators using the above method, like string, float, Int64, etc. I don't think this is a good approach.
Alternatively, you can try to convert them to dynamic and just apply an operator then, but since this will throw an exception, if the operator is not defined, and seems very unelegant to me, I would still like to try and find a better way of doing this.
TryMultiply<float, string>(5.0f, "abc", out var a);
bool TryMultiply<TA, TB>(TA a, TB b, out object result)
{
try
{
dynamic dA = (dynamic)a;
dynamic dB = (dynamic)b;
result = dA * dB;
return true;
}
catch (RuntimeBinderException e)
{
result = default;
return false;
}
}
And even then, you only know, that the * operator is not defined for float and string. But you cannot make a statement about any other types, which renders this approach basically useless.