I am trying to implement a generic operator like so:
class Foo
{
public static T operator +<T>(T a, T b)
{
// Do something with a and b that makes sense for operator + here
}
}
Really what I'm trying to do is gracefully handle inheritance. With a standard operator + in Foo, where T is instead "Foo", if anyone is derived from Foo (say Bar inherits Foo), then a Bar + Bar operation will still return a Foo. I was hoping to solve this with a generic operator +, but I just get a syntax error for the above (at the <) making me believe that such code is not legal.
Is there a way to make a generic operator?
No, you can't declare generic operators in C#.
Operators and inheritance don't really mix well.
If you want Foo + Foo to return a Foo and Bar + Bar to return a Bar, you will need to define one operator on each class. But, since operators are static, you won't get the benefits of polymorphism because which operator to call will be decided at compile-time:
Foo x = new Bar();
Foo y = new Bar();
var z = x + y; // calls Foo.operator+;
https://jonskeet.uk/csharp/miscutil/usage/genericoperators.html
static T Add<T>(T a, T b) {
//TODO: re-use delegate!
// declare the parameters
ParameterExpression paramA = Expression.Parameter(typeof(T), "a"),
paramB = Expression.Parameter(typeof(T), "b");
// add the parameters together
BinaryExpression body = Expression.Add(paramA, paramB);
// compile it
Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
// call it
return add(a,b);
}
You can just define operator in a generic class Foo.
You can also create real generic operators, but C# compiler won't use them.
[System.Runtime.CompilerServices.SpecialName]
public static T op_Addition<T>(T a, T b) { ... }
You cannot declare generic operators in C# - I am not sure on the reasoning but assume it's a usefulness vs effort thing for the implementation team (I believe there might be a post on here with Jon Skeet discussing it, or perhaps on his blog when he discussed things he'd like to see in C#).
Indeed, you cannot even use operators with generics in C#.
This is because generics must be applicable for all possible types that could be provided. This is why you must scope the generic type to classes when you want to use == as below:
void IsEqual<T>(T x, T y) where T : class
{
return x == y;
}
Unfortunately you cannot do:
void Add<T>(T x, T y) where T : operator +
{
return x + y;
}
You might also be interested in this short summary article I came across.
Was searching for the same thing and google brought me here....
I wasn't too happy about the accepted answer and was looking for a workaround.
I managed to implement this using generics. Here is the Foo and Bar class:
class Foo
{
private int value;
public Foo(int x)
{
value = x;
}
public virtual int getVal()
{
return value;
}
}
class Bar : Foo
{
private int derivedValue;
public Bar(int x):base(x)
{
derivedValue = x;
}
public override int getVal()
{
return derivedValue;
}
}
Then a generic class containing the operators but restricted to type of Foo and derived from Foo:
class GenericOp<T> where T : Foo
{
private T value;
public GenericOp(T x)
{
value = x;
}
public static Foo operator +(GenericOp<T> a, GenericOp<T> b)
{
return new Foo(a.value.getVal() + b.value.getVal());
}
}
Some usage code showing you always get back a Foo as well as preventing you from mixing the types:
Foo f1 = new Foo(1);
Foo f2 = new Foo(2);
Bar b1 = new Bar(10);
Bar b2 = new Bar(20);
GenericOp<Foo> left = new GenericOp<Foo>(f1);
GenericOp<Foo> right = new GenericOp<Foo>(f2);
Foo res = left + right;
GenericOp<Bar> left1 = new GenericOp<Bar>(b1);
GenericOp<Bar> right1 = new GenericOp<Bar>(b2);
Foo res1 = left1 + right1;
GenericOp<Foo> left2 = new GenericOp<Foo>(f1);
GenericOp<Bar> right2 = new GenericOp<Bar>(b1);
//Foo res2 = left2 + right2; //this fails and rightfully so.
This is now possible in C# 11 via static abstract interface methods; for example:
public interface IMyInterface<T> where T : IMyInterface<T>
{
static abstract T operator +(T left, T right);
}
which you can then use via where T : IMyInterface<T> as:
class Bar
{
static T Add<T>(T x, T y, T z) where T : IMyInterface<T>
{
return x + y + z;
}
}
The problem, though, is that every T you want would need to implement IMyInterface<T>, which isn't possible for pre-defined types (like int, float, etc) which you don't control. The good news is that .NET 7 does this for you, for all the types you might think of, so in reality you don't need to define your own API; instead, you might use the system-defined interface INumber<T>:
static T Add<T>(T x, T y, T z) where T : INumber<T>
{
return x + y + z;
}
Related
Basically I want to use my own types instead of primitives like int/double, but still pass around these primitive values. Something like:
interface IInt {} // My interface to represent int. If I could fake so "int" implements this, all would work.
interface IPostNumber : IInt {} // Post number is an int. But int is not type safe enough for me.
void MyFunction(IPostNumber postNumber); // My function that should accept int/IPostNumber.
MyFunction(42); // This could also work with implicit conversion, but not allowed for interfaces:(
From ispiro's suggestion I found something that should cover everything.
So I declare my interfaces independent of underlying representation, e.g.
public interface IPostNumber{}
public interface IPostNumberFrom : IPostNumber{}
public interface IPostNumberTo : IPostNumber{}
These have full interface generality such as multiple inheritance. Then the data representation is done with generic classes with implicit conversion:
public class CInt<T>
{
public int value;
public static implicit operator int(CInt<T> d) => d.value;
public static implicit operator CInt<T>(int b) => new CInt<T>() { value = b };
}
Functions that accepts IPostNumber with int, is done as such:
private int TestPostNumberInt(CInt<IPostNumber> i) => i;
private int TestPostNumberFrom(CInt<IPostNumberFrom> i) => i;
CInt<IPostNumber> a = 4; // Works
Assert.Equal(1, TestPostNumberInt(1)); // Works
Assert.Equal(1, TestPostNumberFrom(a)); // Don't compile with IPostNumber into IPostNumberFrom
Now I can always declare CString<IPostNumber>, if some post numbers are represented with string. Or a function could accept the IPostNumber interface itself, if I make some class of it. Now one little issue is that if I want to pass CInt<IPostNumberFrom> to TestPostNumber, the method must be generic with T : IPostNumber, like this:
private int TestPostNumberInt<T>(CInt<T> i) where T : IPostNumber => i;
private int TestPostNumberIntFrom<T>(CInt<T> i) where T : IPostNumberFrom => i;
and then the generic type will not be detected while using implicit conversion (must cast). But we'll see if this is a big deal.
Also for later consideration: I will have class CJSON<T> : CString<T>. From what I see it works, though argubly CJSON could have different representations as well, like byte[] in some context. (But this is taking things far). So just need to think hard about representation vs. interfaces for my domain concepts.
I think what you might be looking for are implicit operators, but unfortunately I believe they're not supported for interfaces in the C# language specification. You can do this with subclasses if need be. Here's an example:
public class MyInt
{
int SomeValue;
public TestInt(int i)
{
SomeValue = i;
}
public static implicit operator MyInt(int i)
{
return new MyInt(i);
}
public static implicit operator int(MyInt myInt)
{
return myInt.SomeValue;
}
}
To assign using an implicit operator, you can do this:
MyInt n = 3;
int x = n;
See: implicit operator using interfaces
Is it this you're looking for?
public class IInt
{
public int TheInt;
public IInt(int theInt)
{
TheInt = theInt;
}
}
and then either use:
IInt i = new IInt(42);
MyFunction(i);
or define MyFunction for int and then use:
IInt i = new IInt(42);
MyFunction(i.TheInt);
Just one more idea:
public class IInt<T> where T : struct
{
public T TheInt;
public IInt(T theInt)
{
TheInt = theInt;
}
}
You can create an extension method but that method should be explicitly called.
So I wanted to use polymorphism for using arithmetic.
Thus my first thought was to make an interface for using arithmetic, IAddable and such; But I found on the internet that this was not possible. But a trick came into my mind and now I wonder: is this a nice and fast implementation of polymorphism?
public abstract class RingElement
{
public static RingElement operator +(RingElement e1, RingElement e2)
{
if (e1 == null)
return e2;
if (e2 == null)
return e1;
Type type = e1.GetType();
return (RingElement) type.GetMethod("op_Addition").Invoke(null, new object[] {e1, e2 });
}
public static RingElement operator *(RingElement e1, RingElement e2)
{
if (e1 == null)
return e2;
if (e2 == null)
return e1;
Type type = e1.GetType();
return (RingElement) type.GetMethod("op_Multiply").Invoke(null, new object[] { e1, e2 });
}
}
I made two RingElements: a doubleElement (just containing a double) and a generic
Matrix<T> : RingElement where T : RingElement
The null handling is to implement the possibility of empty sums or empty products.
Every inherited class of RingElement should have two static methods
public static T operator +(T x, T y)
public static T operator *(T x, T y)
with their own body of implementation, where T is the class type
That will work, the bit using reflection does the trick. It is not type-safe and might not be the most performant way but unfortunately there is not really a completely satisfactory answer to your problem in C# yet.
Here are a couple suggestions you might find useful:
To address the valid concern of Scott Hannen, about being able to add a DogRingElement : RingElement to a CatRingElement : RingElement you can use the strangely recurring pattern,
public abstract class RingElement<T> where T : RingElement<T> { .. }
public class DogRingElement : RingElement<DogRingElement> { .. }
public class CatRingElement : RingElement<CatRingElement> { .. }
To help a bit with performance you might try,
public static RingElement operator +(RingElement e1, RingElement e2)
{
return (RingElement) ((dynamic) e1 + (dynamic) e2);
}
This has a somewhat large performance hit at the beginning but gets faster after the first use.
you could use dynamic variables in your Matrix implementation,
class Matrix<T>
{
public static Matrix<T> operator + (Matrix<T> a, Matrix<T> b)
{
// check a.M = b.M, a.N = b.N
var c = new Matrix<T>(a.M, a.N);
for (var i = 0; i < a.N ; i ++)
{
for (var i = 0; i < a.N ; i ++)
{
dynamic x = a[i, j], y = b[i, j];
c[i,j] = (T) (x + y);
}
}
return c;
}
}
The performance is not fantastic first time it is used but gets descent afterwards.
You could also consider a wrapper class implementing the arithmetic operators, holding a reference to an object implementing an interface with Add, Mult etc.. methods,
public interface IRingElem<T> // strangely recurring pattern
where T : IRingElem<T>
{
T Add(T);
}
public class Num<T>
where T : IRingElem<T>
{
private readonly T elem;
public static Num<T> operator + (Num<T> a, Num<T> b)
{
return new Num<T>(a.elem.Add(b.elem));
}
}
by implementing explicit cast from T to Num<T> and implicit cast from Num<T> to T this is reasonably confortable.
If you are after really good performance you might consider making the wrapper class a struct (removing the readonly sometimes helps also) and using [MethodImpl(MethodImplOptions.AggressiveInlining)] everywhere in the wrapper class.
You are a bit too early )). There are Type Classes candidate in c# 9 (link) which would be probably most elegant solution in c#.
(If using f# is an option, it already has Statically Resolved Type Parameters, and the page under this link exactly shows an example of polymorphism for arithmetic)
As I'm not exactly an expert on programming languages I'm well aware this may be a stupid question, but as best as I can tell C# handles anonymous methods and closures by making them into instance methods of an anonymous nested class [1], instantiating this class, and then pointing delegates at those instance methods.
It appears that this anonymous class can only ever be instantiated once (or am I wrong about that?), so why not have the anonymous class be static instead?
[1] Actually, it looks like there's one class for closures and one for anonymous methods that don't capture any variables, which I don't entirely understand the rationale for either.
I'm well aware this may be a stupid question
It's not.
C# handles anonymous methods and closures by making them into instance methods of an anonymous nested class, instantiating this class, and then pointing delegates at those instance methods.
C# does that sometimes.
It appears that this anonymous class can only ever be instantiated once (or am I wrong about that?), so why not have the anonymous class be static instead?
In cases where that would be legal, C# does you one better. It doesn't make a closure class at all. It makes the anonymous function a static function of the current class.
And yes you are wrong about that. In cases where you can get away with only allocating the delegate once, C# does get away with it.
(This is not strictly speaking entirely true; there are some obscure cases where this optimization is not implemented. But for the most part it is.)
Actually, it looks like there's one class for closures and one for anonymous methods that don't capture any variables, which I don't entirely understand the rationale for either.
You have put your finger on the thing you don't adequately understand.
Let's look at some examples:
class C1
{
Func<int, int, int> M()
{
return (x, y) => x + y;
}
}
This can be generated as
class C1
{
static Func<int, int, int> theFunction;
static int Anonymous(int x, int y) { return x + y; }
Func<int, int, int> M()
{
if (C1.theFunction == null) C1.theFunction = C1.Anonymous;
return C1.theFunction;
}
}
No new class needed.
Now consider:
class C2
{
static int counter = 0;
int x = counter++;
Func<int, int> M()
{
return y => this.x + y;
}
}
Do you see why this cannot be generated with a static function? The static function would need access to this.x but where is the this in a static function? There isn't one.
So this one has to be an instance function:
class C2
{
static int counter = 0;
int x = counter++;
int Anonymous(int y) { return this.x + y; }
Func<int, int> M()
{
return this.Anonymous;
}
}
Also, we can no longer cache the delegate in a static field; do you see why?
Exercise: could the delegate be cached in an instance field? If no, then what prevents this from being legal? If yes, what are some arguments against implementing this "optimization"?
Now consider:
class C3
{
static int counter = 0;
int x = counter++;
Func<int> M(int y)
{
return () => x + y;
}
}
This cannot be generated as an instance function of C3; do you see why? We need to be able to say:
var a = new C3();
var b = a.M(123);
var c = b(); // 123 + 0
var d = new C3();
var e = d.M(456);
var f = e(); // 456 + 1
var g = a.M(789);
var h = g(); // 789 + 0
Now the delegates need to know not just the value of this.x but also the value of y that was passed in. That has to be stored somewhere, so we store it in a field. But it can't be a field of C3, because then how do we tell b to use 123 and g to use 789 for the value of y? They have the same instance of C3 but two different values for y.
class C3
{
class Locals
{
public C3 __this;
public int __y;
public int Anonymous() { return this.__this.x + this.__y; }
}
Func<int> M(int y)
{
var locals = new Locals();
locals.__this = this;
locals.__y = y;
return locals.Anonymous;
}
}
Exercise: Now suppose we have C4<T> with a generic method M<U> where the lambda is closed over variables of types T and U. Describe the codegen that has to happen now.
Exercise: Now suppose we have M return a tuple of delegates, one being ()=>x + y and the other being (int newY)=>{ y = newY; }. Describe the codegen for the two delegates.
Exercise: Now suppose M(int y) returns type Func<int, Func<int, int>> and we return a => b => this.x + y + z + a + b. Describe the codegen.
Exercise: Suppose a lambda closed over both this and a local does a base non-virtual call. It is illegal to do a base call from code inside a type not directly in the type hierarchy of the virtual method, for security reasons. Describe how to generate verifiable code in this case.
Exercise: Put 'em all together. How do you do codegen for multiple nested lambdas with getter and setter lambdas for all locals, parameterized by generic types at the class and method scope, that do base calls? Because that's the problem that we actually had to solve.
I currently have a user defined type
class MyType {
double x;
double y;
double z;
//This class has operator overloading implemented
public static MyType operator + (double a,MyType b){
...
}
}
At some point later I will have an array (object[]) some of them double and some MyType. I would like to do evaluation over them but compiler is not allowing operator '+' to be applied to type object and object. What should I do here?
When resolving a + in code the compiler needs to bind it to a specific operation. The type object has no + operation and the compiler has no idea that the underlying types are double and MyType and hence the compiler errors out.
In order to fix this you will need to either
statically convert the elements to double and MyType so the compiler can properly bind the + operator
use dynamic and rely on the runtime binding to the correct operator+.
Here is an example of the latter method.
class MyType {
double _value;
internal MyType(double value) {
_value = value;
}
public static MyType operator +(double left, MyType right) {
return new MyType(left + right._value);
}
public static MyType operator +(MyType left, double right) {
return new MyType(left._value + right);
}
public static MyType operator +(MyType left, MyType right) {
return new MyType(left._value + right._value);
}
public static implicit operator MyType(double other) {
return new MyType(other);
}
}
class Program
{
static void Main(string[] args) {
object[] them = new object[] {
42,
new MyType(13),
12,
new MyType(12)
};
dynamic all = them;
MyType sum = 0;
foreach (dynamic element in all) {
sum += element;
}
Console.WriteLine(sum);
}
}
Honestly, I would create a MyType constructor that took a single double parameter, and use that to convert each double to a MyType, so that you could just use a MyType[] (or List<MyType>).
I understand that's really not what you're asking, but you'd still be able to handle the MyType creation such that the addition will perform properly, and you'd be more type-safe with your array.
You should be more specific with your types - the reason you cannot add is because object could be anyting in the system.
Is there any way that you can change object for a more specific type?
If it absolutely has to be object then you will have to evaluate at run-time using casts or the as operator or some similar mechanism.
eg
public static MyType operator +(object o, MyType b)
{
MyOtherType mot = o as MyOtherType;
if(o!=null)
...
but be in no doubt that your solution here raises questions about your design choices
How would you do specialization in C#?
I'll pose a problem. You have a template type, you have no idea what it is. But you do know if it's derived from XYZ you want to call .alternativeFunc(). A great way is to call a specialized function or class and have normalCall return .normalFunc() while have the other specialization on any derived type of XYZ to call .alternativeFunc(). How would this be done in C#?
In C#, the closest to specialization is to use a more-specific overload; however, this is brittle, and doesn't cover every possible usage. For example:
void Foo<T>(T value) {Console.WriteLine("General method");}
void Foo(Bar value) {Console.WriteLine("Specialized method");}
Here, if the compiler knows the types at compile, it will pick the most specific:
Bar bar = new Bar();
Foo(bar); // uses the specialized method
However....
void Test<TSomething>(TSomething value) {
Foo(value);
}
will use Foo<T> even for TSomething=Bar, as this is burned in at compile-time.
One other approach is to use type-testing within a generic method - however, this is usually a poor idea, and isn't recommended.
Basically, C# just doesn't want you to work with specializations, except for polymorphism:
class SomeBase { public virtual void Foo() {...}}
class Bar : SomeBase { public override void Foo() {...}}
Here Bar.Foo will always resolve to the correct override.
Assuming you're talking about template specialization as it can be done with C++ templates - a feature like this isn't really available in C#. This is because C# generics aren't processed during the compilation and are more a feature of the runtime.
However, you can achieve similar effect using C# 3.0 extension methods. Here is an example that shows how to add extension method only for MyClass<int> type, which is just like template specialization. Note however, that you can't use this to hide default implementation of the method, because C# compiler always prefers standard methods to extension methods:
class MyClass<T> {
public int Foo { get { return 10; } }
}
static class MyClassSpecialization {
public static int Bar(this MyClass<int> cls) {
return cls.Foo + 20;
}
}
Now you can write this:
var cls = new MyClass<int>();
cls.Bar();
If you want to have a default case for the method that would be used when no specialization is provided, than I believe writing one generic Bar extension method should do the trick:
public static int Bar<T>(this MyClass<T> cls) {
return cls.Foo + 42;
}
I was searching for a pattern to simulate template specialization, too. There are some approaches which may work in some circumstances. However what about the case
static void Add<T>(T value1, T value2)
{
//add the 2 numeric values
}
It would be possible to choose the action using statements e.g. if (typeof(T) == typeof(int)). But there is a better way to simulate real template specialization with the overhead of a single virtual function call:
public interface IMath<T>
{
T Add(T value1, T value2);
}
public class Math<T> : IMath<T>
{
public static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();
//default implementation
T IMath<T>.Add(T value1, T value2)
{
throw new NotSupportedException();
}
}
class Math : IMath<int>, IMath<double>
{
public static Math P = new Math();
//specialized for int
int IMath<int>.Add(int value1, int value2)
{
return value1 + value2;
}
//specialized for double
double IMath<double>.Add(double value1, double value2)
{
return value1 + value2;
}
}
Now we can write, without having to know the type in advance:
static T Add<T>(T value1, T value2)
{
return Math<T>.P.Add(value1, value2);
}
private static void Main(string[] args)
{
var result1 = Add(1, 2);
var result2 = Add(1.5, 2.5);
return;
}
If the specialization should not only be called for the implemented types, but also derived types, one could use an In parameter for the interface. However, in this case the return types of the methods cannot be of the generic type T any more.
By adding an intermediate class and a dictionary, specialization is possible.
To specialize on T, we create an generic interface, having a method called (e.g.) Apply. For the specific classes that interface is implemented, defining the method Apply specific for that class. This intermediate class is called the traits class.
That traits class can be specified as a parameter in the call of the generic method, which then (of course) always takes the right implementation.
Instead of specifying it manually, the traits class can also be stored in a global IDictionary<System.Type, object>. It can then be looked up and voila, you have real specialization there.
If convenient you can expose it in an extension method.
class MyClass<T>
{
public string Foo() { return "MyClass"; }
}
interface BaseTraits<T>
{
string Apply(T cls);
}
class IntTraits : BaseTraits<MyClass<int>>
{
public string Apply(MyClass<int> cls)
{
return cls.Foo() + " i";
}
}
class DoubleTraits : BaseTraits<MyClass<double>>
{
public string Apply(MyClass<double> cls)
{
return cls.Foo() + " d";
}
}
// Somewhere in a (static) class:
public static IDictionary<Type, object> register;
register = new Dictionary<Type, object>();
register[typeof(MyClass<int>)] = new IntTraits();
register[typeof(MyClass<double>)] = new DoubleTraits();
public static string Bar<T>(this T obj)
{
BaseTraits<T> traits = register[typeof(T)] as BaseTraits<T>;
return traits.Apply(obj);
}
var cls1 = new MyClass<int>();
var cls2 = new MyClass<double>();
string id = cls1.Bar();
string dd = cls2.Bar();
See this link to my recent blog and the follow ups for an extensive description and samples.
I think there is a way to achieve it with .NET 4+ using dynamic resolution:
static class Converter<T>
{
public static string Convert(T data)
{
return Convert((dynamic)data);
}
private static string Convert(Int16 data) => $"Int16 {data}";
private static string Convert(UInt16 data) => $"UInt16 {data}";
private static string Convert(Int32 data) => $"Int32 {data}";
private static string Convert(UInt32 data) => $"UInt32 {data}";
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Converter<Int16>.Convert(-1));
Console.WriteLine(Converter<UInt16>.Convert(1));
Console.WriteLine(Converter<Int32>.Convert(-1));
Console.WriteLine(Converter<UInt32>.Convert(1));
}
}
Output:
Int16 -1
UInt16 1
Int32 -1
UInt32 1
Which shows that a different implementation is called for different types.
Some of the proposed answers are using runtime type info: inherently slower than compile-time bound method calls.
Compiler does not enforce specialization as well as it does in C++.
I would recommend looking at PostSharp for a way to inject code after the usual compiler is done to achieve an effect similar to C++.
A simpler, shorter and more readable version of what #LionAM proposed (about half of the code size), shown for lerp since this was my actual use case:
public interface ILerp<T> {
T Lerp( T a, T b, float t );
}
public class Lerp : ILerp<float>, ILerp<double> {
private static readonly Lerp instance = new();
public static T Lerp<T>( T a, T b, float t )
=> ( instance as ILerp<T> ?? throw new NotSupportedException() ).Lerp( a, b, t );
float ILerp<float>.Lerp( float a, float b, float t ) => Mathf.Lerp( a, b, t );
double ILerp<double>.Lerp( double a, double b, float t ) => Mathd.Lerp( a, b, t );
}
You can then just e.g.
Lerp.Lerp(a, b, t);
in any generic context, or provide the method as a grouped Lerp.lerp method reference matching T(T,T,float) signature.
If ClassCastException is good enough for you, you can of course just use
=> ( (ILerp<T>) instance ).Lerp( a, b, t );
to make the code even shorter/simpler.
If you just want to test if a type is derrived from XYZ, then you can use:
theunknownobject.GetType().IsAssignableFrom(typeof(XYZ));
If so, you can cast "theunknownobject" to XYZ and invoke alternativeFunc() like this:
XYZ xyzObject = (XYZ)theunknownobject;
xyzObject.alternativeFunc();
Hope this helps.