I need to return a method in an operator function.
public int Add()
{
return 1;
}
public static int operator +()
{
return Add;
}
I will need to do this for a multiply, subtract and divide operator/function too.
Thanks
You can't declare parameterless operators. You can declare an operator to return an appropriate delegate - e.g. Func<int> - but it would be a pretty odd thing to do, IMO.
If you can tell us more about what you're trying to achieve, we can probably help you to work out a cleaner design.
Here's a pretty strange example overloading the unary + operator:
using System;
class Weird
{
private readonly int amount;
public Weird(int amount)
{
this.amount = amount;
}
private int Add(int original)
{
return original + amount;
}
// Very strange. Please don't do this.
public static Func<int, int> operator +(Weird weird)
{
return weird.Add;
}
}
class Test
{
static void Main(string[] args)
{
Weird weird = new Weird(2);
Func<int, int> func = +weird;
Console.WriteLine(func(3));
}
}
EDIT: If you're just trying to implement a Rational type, you're more likely to want:
public struct Rational
{
// Other members
public Rational Add(Rational other)
{
...
}
public static Rational operator +(Rational left, Rational right)
{
return left.Add(right);
}
}
This is what you SEEM to be trying to do, but your example makes it difficult to tell. So, from your comments in other answers it looks like you want to add, subtract, multiply, divide Rational numbers, which means the result should be a Rational as well (not an int).
Thus, you could define each of your methods, then implement operators to call those. The operators are always static, thus you'd need to check for null and handle as appropriate (in this case, I'll just throw ArgumentNullException):
public class Rational
{
public Rational Add(Rational other)
{
if (other == null) throw new ArgumentNullException("other");
return // <-- return actual addition result here
}
public static Rational operator +(Rational left, Rational right)
{
if (left == null) throw new ArgumentNullException("left");
return left.Add(right);
}
public Rational Subtract(Rational other)
{
if (other == null) throw new ArgumentNullException("other");
return // <-- return actual subtraction result here
}
public static Rational operator -(Rational left, Rational right)
{
if (left == null) throw new ArgumentNullException("left");
return left.Subtract(right);
}
public Rational Multiply(Rational other)
{
if (other == null) throw new ArgumentNullException("other");
return // <-- return actual multiplication result here
}
public static Rational operator *(Rational left, Rational right)
{
if (left == null) throw new ArgumentNullException("left");
return left.Multiply(right);
}
public Rational Divide(Rational other)
{
if (other == null) throw new ArgumentNullException("other");
return // <-- return actual division result here
}
public static Rational operator /(Rational left, Rational right)
{
if (left == null) throw new ArgumentNullException("left");
return left.Divide(right);
}
}
Simple. Just call the Add method:
return Add();
C Sharp - Lesson 18: Overloading Operators
I don't think you can overload the + operator for int's! You would have to create your own wrapper class or struct instead:
public struct MyInt
{
private int _value;
public MyInt(int value)
{
_value = value;
}
public int Value
{
get { return _value; }
}
public static MyInt operator +(MyInt a, MyInt b)
{
return new MyInt(a._value + b._value);
}
public static implicit operator MyInt(int intValue)
{
return new MyInt(intValue);
}
public static explicit operator int(MyInt x)
{
return x.Value;
}
}
Then you are free to do with '+' what ever you want to do with it.
The implicit operator automatically converts int's to MyInt. So you could assign like this: MyInt x = 7;
The explicit operator converts MyInt's to int's like: int i = (int)x; where x is a MyInt.
Related
I want to implement my own CustomNumber class, and have it comparable to all other primitive number datatypes (int, long, double, float, etc.) using the relational operators.
Is there a way to do that for all of them at once, or do I really have to override the ==, !=, >, <, >= and <= operators aswell as the Equals(T other) method for each single integral datatype?
I think I know how operator overloading works in general, but it feels like there must be some kind of shortcut in order to make my CustomNumber comparable to all primitive number datatypes using relational operators, instead of having to overload each of those 6 operators for each single datatype, which might quickly add up to about 100 overload definitions.
There is no shortcut per se, you have to implement all the operators and functionality for all the types you want to support, it can't read your mind.
Check out the decimal implementation.
For your sanity you will notice not everything needs to be overridden, this is done by the implementation of implicit operators:
public static implicit operator Decimal(byte value)
{
return new Decimal(value);
}
[CLSCompliant(false)]
public static implicit operator Decimal(sbyte value)
{
return new Decimal(value);
}
public static implicit operator Decimal(short value)
{
return new Decimal(value);
}
[CLSCompliant(false)]
public static implicit operator Decimal(ushort value)
{
return new Decimal(value);
}
public static implicit operator Decimal(char value)
{
return new Decimal(value);
}
public static implicit operator Decimal(int value)
{
return new Decimal(value);
}
[CLSCompliant(false)]
public static implicit operator Decimal(uint value)
{
return new Decimal(value);
}
public static implicit operator Decimal(long value)
{
return new Decimal(value);
}
[CLSCompliant(false)]
public static implicit operator Decimal(ulong value)
{
return new Decimal(value);
}
public static explicit operator Decimal(float value)
{
return new Decimal(value);
}
public static explicit operator Decimal(double value)
{
return new Decimal(value);
}
public static explicit operator byte(Decimal value)
{
return ToByte(value);
}
[CLSCompliant(false)]
public static explicit operator sbyte(Decimal value)
{
return ToSByte(value);
}
public static explicit operator char(Decimal value)
{
UInt16 temp;
try
{
temp = ToUInt16(value);
}
catch (OverflowException e)
{
throw new OverflowException(Environment.GetResourceString("Overflow_Char"), e);
}
return (char)temp;
}
public static explicit operator short(Decimal value)
{
return ToInt16(value);
}
[CLSCompliant(false)]
public static explicit operator ushort(Decimal value)
{
return ToUInt16(value);
}
public static explicit operator int(Decimal value)
{
return ToInt32(value);
}
[CLSCompliant(false)]
public static explicit operator uint(Decimal value)
{
return ToUInt32(value);
}
public static explicit operator long(Decimal value)
{
return ToInt64(value);
}
[CLSCompliant(false)]
public static explicit operator ulong(Decimal value)
{
return ToUInt64(value);
}
public static explicit operator float(Decimal value)
{
return ToSingle(value);
}
public static explicit operator double(Decimal value)
{
return ToDouble(value);
}
public static Decimal operator +(Decimal d)
{
return d;
}
public static Decimal operator -(Decimal d)
{
return Negate(d);
}
public static Decimal operator ++(Decimal d)
{
return Add(d, One);
}
public static Decimal operator --(Decimal d)
{
return Subtract(d, One);
}
[System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator +(Decimal d1, Decimal d2)
{
FCallAddSub(ref d1, ref d2, DECIMAL_ADD);
return d1;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator -(Decimal d1, Decimal d2)
{
FCallAddSub(ref d1, ref d2, DECIMAL_NEG);
return d1;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator *(Decimal d1, Decimal d2)
{
FCallMultiply(ref d1, ref d2);
return d1;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static Decimal operator /(Decimal d1, Decimal d2)
{
FCallDivide(ref d1, ref d2);
return d1;
}
public static Decimal operator %(Decimal d1, Decimal d2)
{
return Remainder(d1, d2);
}
[System.Security.SecuritySafeCritical] // auto-generated
public static bool operator ==(Decimal d1, Decimal d2)
{
return FCallCompare(ref d1, ref d2) == 0;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static bool operator !=(Decimal d1, Decimal d2)
{
return FCallCompare(ref d1, ref d2) != 0;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static bool operator <(Decimal d1, Decimal d2)
{
return FCallCompare(ref d1, ref d2) < 0;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static bool operator <=(Decimal d1, Decimal d2)
{
return FCallCompare(ref d1, ref d2) <= 0;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static bool operator >(Decimal d1, Decimal d2)
{
return FCallCompare(ref d1, ref d2) > 0;
}
[System.Security.SecuritySafeCritical] // auto-generated
public static bool operator >=(Decimal d1, Decimal d2)
{
return FCallCompare(ref d1, ref d2) >= 0;
}
As partial shortcut you can limit your overrides to double which cover all regular "numeric" types at cost of compiler inserted cast. Always comparing to double is dangerous for larger integer values (int and smaller types will be precise always).
class MyType
{
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator == (MyType x, double c)
{
// write some real code here - this one does not have a value to compare to.
return c > 42;
}
// you need all several overrides for each operator to behave in expected way
// so calling the same one (a == b)
// from a != b, b != a, b == a is a way to keep them consistent
public static bool operator == (double c, MyType x)
{
return (x == c);
}
public static bool operator != (double c, MyType x)
{
return !(c == x);
}
public static bool operator != (MyType x, double c)
{
return !(x == c);
}
}
Notes
C#/ .NET do not have built in concept of "numeric" type - this is something people ask often enough (i.e. Is there a constraint that restricts my generic method to numeric types?, Generics - where T is a number?).
don't forget to implement IEquatable<T>, IComparable, IComparable<T>...
consider if it is actually useful for your "numbers" to be able to freely mix with other types - especially for comparison with imprecise float/double which already painful enough.
I have a struct representing a Measure in my program, which I want to be interchangeable with double.
I have implemented it, and everything seems to be working fine, except for one of my tests:
[Test]
public void TestMeasureDefaultConstructor()
{
Measure m = new Measure();
// These pass
Assert.That(m.Equals(0), Is.True);
Assert.That(0 == m, Is.True);
Assert.That((double) m, Is.EqualTo(0));
Assert.That((float) m, Is.EqualTo(0));
Assert.That(0, Is.EqualTo(m));
// The next two fail
Assert.That(m, Is.EqualTo(0.0));
Assert.That(0.0.Equals(m), Is.True);
}
Everything works up to the line with Is.EqualTo(0.0).
The two lines testing that 0.0 Equals m each fail as follows:
Message: Expected: 0.0d
But was: MyCode.Model.Measure
(obviously only the first fails, so I have to swap them round to prove this).
I have clearly implemented Equals for my Measure class sufficiently, but I can't work out how to extend double.Equals to make the last two work. I have done a lot of searches, but keep coming on how to implement Equals for my class rather than the other way round.
Here is my class, possibly overkill now after trying all sorts of ways to make it work:
/// <summary>
/// The Measure class encapsulates the unit of measurement.
/// </summary>
public struct Measure
{
#region Construction and destruction
public Measure(double v)
{
Value = v;
}
#endregion
#region Conversions
public static implicit operator Measure(double v)
{
return new Measure(v);
}
public static implicit operator double(Measure m)
{
return m.Value;
}
public static implicit operator float(Measure m)
{
return (float) m.Value;
}
#endregion
#region Properties
public double Value { get; set; }
#endregion
#region Equality
public static bool Equals(Measure a, Measure b)
{
// Constants.IsEqual checks abs(a - b) < Tolerance.
return Constants.IsEqual(a.Value, b.Value);
}
public static bool Equals(Measure a, object b)
{
return a.Equals(b);
}
public static bool Equals(object a, Measure b)
{
return b.Equals(a);
}
public bool Equals(Measure other)
{
return Equals(this, other);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
return false;
try
{
double d = Convert.ToDouble(obj);
return Equals(d);
}
catch (InvalidCastException)
{
return false;
}
catch (Exception e)
{
// Shouldn't get here!
Debug.Print("Unexpected exception in Measure.Equals: ", e);
if (System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Break();
return false;
}
}
public static bool operator == (Measure x, Measure y)
{
return x.Equals(y);
}
public static bool operator != (Measure x, Measure y)
{
return !(x == y);
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
#endregion
}
I have created a couple of extension methods:
public static class ExtensionMethods
{
public static bool Equals(this object a, Measure b)
{
return b.Equals(a);
}
public static bool Equals(this double a, Measure b)
{
return b.Equals(a);
}
}
I have put breakpoints on every Equals function, and they get hit during the passing tests, but none of these functions gets called for double.Equals so clearly the compiler doesn't think any of them are compatible.
Is this possible? If so, what am I missing, and how do I implement it?
Thanks in advance for any pointers.
Ian
Updated: How could I make a method with two paramerters to take any primitive number type, like int, uint, float, double, etc, (except bool)?
I'm currently using an object, but that means the method can accept any type.
public int[] MyNumberMethod(object a, object b)
{
if (a is int || a is uint || a is short || a is ushort || a is long || a is ulong || a is byte || a is sbyte || a is float || a is double || a is decimal)
{
if (b is int || b is uint || b is short || b is ushort || b is long || b is ulong || b is byte || b is sbyte || b is float || b is double || b is decimal)
return new int[] { Convert.ToInt32(b), Convert.ToInt32(a) };
}
return new int[] { 0, 0 };
}
This might not be as good as the other answers, but another option is to create your own structure where you only allow a value of certain data types:
public struct Number
{
#region Static methods and fields
private static readonly Type[] allowedTypes = new Type[] {
typeof(int), typeof(uint), typeof(short), typeof(ushort),
typeof(long), typeof(ulong), typeof(byte), typeof(sbyte),
typeof(float), typeof(double), typeof(decimal)
};
private static void CheckIsNumber(dynamic val) {
if (Array.IndexOf(allowedTypes, val.GetType()) == -1) { throw new InvalidCastException("Input type must be a number."); }
}
#endregion
#region Constructor
public Number(dynamic Value) {
Number.CheckIsNumber(Value);
_value = Value;
}
#endregion
#region Properties
private dynamic _value;
public dynamic Value {
get { return _value; }
set {
Number.CheckIsNumber(value);
_value = value;
}
}
#endregion
#region Overridden methods
public override bool Equals(object obj) { return _value.Equals(obj); }
public override int GetHashCode() { return _value.GetHashCode(); }
public override string ToString() { return _value.ToString(); }
#endregion
#region Conversion operators - Number
public static implicit operator Number(uint val) { return new Number(val); }
public static implicit operator Number(short val) { return new Number(val); }
public static implicit operator Number(ushort val) { return new Number(val); }
public static implicit operator Number(long val) { return new Number(val); }
public static implicit operator Number(ulong val) { return new Number(val); }
public static implicit operator Number(byte val) { return new Number(val); }
public static implicit operator Number(float val) { return new Number(val); }
public static implicit operator Number(double val) { return new Number(val); }
public static implicit operator Number(decimal val) { return new Number(val); }
#endregion
#region Conversion operators - Misc. data types
public static implicit operator int(Number num) { return (int)num.Value; }
public static implicit operator uint(Number num) { return (uint)num.Value; }
public static implicit operator short(Number num) { return (short)num.Value; }
public static implicit operator ushort(Number num) { return (ushort)num.Value; }
public static implicit operator long(Number num) { return (long)num.Value; }
public static implicit operator ulong(Number num) { return (ulong)num.Value; }
public static implicit operator byte(Number num) { return (byte)num.Value; }
public static implicit operator sbyte(Number num) { return (sbyte)num.Value; }
public static implicit operator float(Number num) { return (float)num.Value; }
public static implicit operator double(Number num) { return (double)num.Value; }
public static implicit operator decimal(Number num) { return (decimal)num.Value; }
#endregion
}
Every time you change the value or create a new instance of the structure it will verify if the input value's data type matches any of the items in the allowedTypes array. If not it will throw an InvalidCastException.
I have also added conversion operators which will let you use this as a normal number, thus you can use it pretty much like you would use any other numerical data type:
Number myNum = 3.5;
myNum += 10.4;
double something = myNum - 6.0;
However keep in mind that you must add a decimal point when working with double, float, etc. or else it will assume that the number is an integer:
Number myNum = 3.5;
myNum -= 2;
MessageBox.Show(myNum.ToString()); //Shows "1" as the second line converts 'myNum' into an integer.
All that said, here's how you would use it for your method:
public int[] MyNumberMethod(Number a, Number b)
{
try {
return new int[] { Convert.ToInt32(b), Convert.ToInt32(a) };
}
catch(InvalidCastException) {
return new int[] { 0, 0 };
}
}
And thanks to the conversion operators you won't need to specify a (Number) conversion. For example:
byte myByte = 133;
//Unnecessary.
MyNumberMethod((Number)17.4, (Number)myByte);
//This works just as fine.
MyNumberMethod(17.4, myByte);
Well since you want to use all primitive types except the bool, how about that?
public int MyNumberMethod<T>(T number) where T : struct
{
if (!(number is bool) && number.GetType().IsPrimitive)
return Convert.ToInt32(number);
return 0;
}
e.g.
MyNumberMethod<short>(5);
All numeric types (except double and float) are implicitly convertible to decimal and float is implicitly convertible to double. So if you make overloads like:
Method(double, double)
Method(decimal, double)
Method(decimal,decimal)
Method(double, decimal)
Your method will be callable with any two numbers but only with any two numbers.
First you must call other function like GenericNumberMethod, that will contain the calling to MyNumberMethod. You must have for each data type an implementacion of GenericNumberMethod with the corresponding parameter
public int MyNumberMethod(object number) {
return Convert.ToInt32(number);
}
public int GenericNumberMethod(int number) {
return MyNumberMethod(number);
}
public int GenericNumberMethod(decimal number) {
return MyNumberMethod(number);
}
I am making a wrapper for a "word" in an emulator project. Its meant to put all my cast conversions all in one spot. I was just about to start implement all the overrides for math functions (+,-,/,8, shift, etc.) When it occured to me that shouldn't all the implicit's take care of that? Do I need to over ride >= and <= when I got > < and ==?
I thought I would ask this as while there are plenty of questions relating to how to create them, there aren't many on how much is enough. Here is the code below:
public struct word_t
{
ulong val;
word_t(ulong val) { this.val = val; }
public static implicit operator word_t(int a) { return new word_t((ulong)a); }
public static implicit operator word_t(long a) { return new word_t((ulong)a); }
public static implicit operator word_t(uint a) { return new word_t((ulong)a); }
public static implicit operator word_t(ulong a) { return new word_t((ulong)a); }
public static implicit operator int(word_t a) { return (int)a.val; }
public static implicit operator long(word_t a) { return (long)a.val; }
public static implicit operator uint(word_t a) { return (uint)a.val; }
public static implicit operator ulong(word_t a) { return (ulong)a.val; }
public static bool operator ==(word_t a, word_t b) { return a.val == b.val; }
public static bool operator !=(word_t a, word_t b) { return a.val != b.val; }
public static bool operator >(word_t a, word_t b) { return a.val > b.val; }
public static bool operator <(word_t a, word_t b) { return a.val < b.val; }
public override bool Equals(object obj) {
return obj.Equals(val);
}
public override int GetHashCode() {
return val.GetHashCode();
}
public override string toString() {
return val.ToString();
}
}
My gut tells me to "Trust the compiler" but my head always worries on how efficient it is.
PS I just realized I should override shifts because of the bit shifting of negative number problems, but for right now just imagine shifts just magically work like adds between uint and int.
I recommend this MSDN article: http://msdn.microsoft.com/en-us/library/8edha89s(v=VS.100).aspx
It shows the operators you can overload and any catches. You can overload <= and >= but they must be overloaded in pairs, as is true with == and != as well.
The complex match operators +=, etc are available if +, etc. is overloaded, etc.
>= and <=, however, are separate. That is, overloading > and == does not give you a >= operator implicitly.
public class Racional<T>
{
private T nominator;
private T denominator;
public T Nominator
{
get { return nominator; }
set { nominator = value; }
}
public T Denominator
{
get { return denominator; }
set { denominator = value; }
}
public Racional(T nominator, T denominator)
{
this.nominator = nominator;
this.denominator = denominator;
}
public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
}
public override string ToString()
{
return "(" + this.nominator + " " + this.denominator + ")";
}
}
I'm interested in this part :
public static Racional<int> operator *(Racional<int> a, Racional<int> b)
{
return ((int)(a.nominator + b.nominator, a.denominator + b.denominator));
}
What's wrong:
One of the parameters of a binary operator must be the containing type
How I can normaly code this part for mathematic operations?
The reason your code doesn't compile is explained by the compiler error. The containing type is a generic type definition, and a generic type constructed from such a type is not considered to be the same type.
I have a few questions:
Why must the Rational type be generic? A rational number is defined as a number that can be expressed as the quotient / fraction of two integers (where the denominator is not 0). Why not make the type non-generic and simply use int throughout? Or do you intend that the type be used for other integral types such as long and BigInteger? In that case, consider using something like Aliostad's suggestion if you want some code-sharing mechanism.
Why do you want the product of two rational numbers to be the equal to the sum of their numerators over the sum of their denominators? That doesn't make sense to me.
In any case, you appear to want to be able to 'generically' add two instances of an 'addable' type. Unfortunately, there currently isn't any way to express a 'has a suitable addition operator' constraint in C#.
Method #1: One workaround for this in C# 4 is to use the dynamic type to give you the desired "virtual operator" semantics.
public static Racional<T> operator *(Racional<T> a, Racional<T> b)
{
var nominatorSum = (dynamic)a.Nominator + b.Nominator;
var denominatorSum = (dynamic)a.Denominator + b.Denominator;
return new Racional<T>(nominatorSum, denominatorSum);
}
The operator will throw if the type doesn't have a suitable addition operator.
Method #2: Another (more efficient) way is to use expression-trees.
First, create and cache a delegate that can perform the addition by compiling the appropriate expression:
private readonly static Func<T, T, T> Adder;
static Racional()
{
var firstOperand = Expression.Parameter(typeof(T), "x");
var secondOperand = Expression.Parameter(typeof(T), "y");
var body = Expression.Add(firstOperand, secondOperand);
Adder = Expression.Lambda<Func<T, T, T>>
(body, firstOperand, secondOperand).Compile();
}
(The static constructor will throw if the type doesn't have a suitable addition operator.)
Then employ it in the operator:
public static Racional<T> operator *(Racional<T> a, Racional<T> b)
{
var nominatorSum = Adder(a.Nominator, b.Nominator);
var denominatorSum = Adder(a.Denominator, b.Denominator);
return new Racional<T>(nominatorSum, denominatorSum);
}
The issue here is you are defining an operator for Racional<int> in the class Racional<T>. This is not possible. The types are not the same, you can only define operator for Racional<T>.
Generics cannot express generalization of operators since they are defined only for a certain types. Solution is to create a class and inherit from Racional<int>:
public class IntRacional : Racional<int>
{
public static Racional<int> operator +(IntRacional a, IntRacional b)
{
return new Racional<int>()
{
Nominator = a.Nominator + b.Nominator,
Denominator = a.Denominator + b.Denominator
};
}
}
To solve your issue, you need to provide conversion functions from T to some type where operator+ is defined and vice versa. Assuming Int64 is big enough in most cases, this can be done this way:
public class Racional<T>
{
private T nominator;
private T denominator;
static Converter<T,Int64> T_to_Int64;
static Converter<Int64,T> Int64_to_T;
public static void InitConverters(Converter<T,Int64> t2int, Converter<Int64,T> int2t )
{
T_to_Int64 = t2int;
Int64_to_T = int2t;
}
public T Nominator
{
get { return nominator; }
set { nominator = value; }
}
public T Denominator
{
get { return denominator; }
set { denominator = value; }
}
public Racional(T nominator, T denominator)
{
this.nominator = nominator;
this.denominator = denominator;
}
public static Racional<T> operator *(Racional<T> a, Racional<T> b)
{
return new Racional<T>(
Int64_to_T(T_to_Int64(a.nominator) + T_to_Int64(b.nominator)),
Int64_to_T(T_to_Int64(a.denominator) + T_to_Int64(b.denominator)));
}
// By the way, should this not be * instead of + ???
//
// public static Racional<T> operator *(Racional<T> a, Racional<T> b)
// {
// return new Racional<T>(
// Int64_to_T(T_to_Int64(a.nominator) * T_to_Int64(b.nominator)),
// Int64_to_T(T_to_Int64(a.denominator) * T_to_Int64(b.denominator)));
// }
public override string ToString()
{
return "(" + this.nominator + " " + this.denominator + ")";
}
}
Of course, this has the drawback that you must provide the initialization of those converters somewhere at the program start, should look like this:
Racional<int>.InitConverters(x => (Int64)x, y => (int)y);
In a real program, you may know which possible replacements for T you are going to use. So one can provide those 3 or 4 calls in a static constructor like this:
public static Racional()
{
Racional<int>.InitConverters(x => (Int64)x, y => (int)y);
Racional<short>.InitConverters(x => (Int64)x, y => (short)y);
Racional<Int64>.InitConverters(x => (Int64)x, y => (Int64)y);
}
should be sufficient in most cases. Note that this converter initialization is repeated for all 3 types 3 times again, re-initializing the conversion functions multiple times again. In practice this should not make any trouble.