First up, I am currently working with VB.NET and therefore not really knowledgeable in C#.
I wanted to create a custom generic Vector class with the constrain, that the type parameter must implement the interface INumber(Of T). However, when I tried to declare a +-operator in said class (using an element-wise addition of values given by two vectors), my VB.NET project produced following error:
Error BC30452 Operator '+' is not defined for types 'T' and 'T'
Since I pretty much only tested the example given on this page and didn't really believe, that Microsoft would publish something that wouldn't work, I decided to also test my problem in C# (also using .NET 7).
For that I build following two MWEs in VB.NET
Vector.vb:
Imports System.Numerics
Public Class Vector(Of T As INumber(Of T))
Private _items() As T
Public Sub New(n As Integer)
ReDim _items(n - 1)
End Sub
Public ReadOnly Property Size As Integer
Get
Return _items.Length
End Get
End Property
Public Function GetValue(i As Integer) As T
Return _items(i)
End Function
Public Sub SetValue(i As Integer, val As T)
_items(i) = val
End Sub
Public Sub SetAll(val As T)
For i As Integer = 0 To _items.Length - 1
_items(i) = val
Next
End Sub
Public Sub Print()
For i As Integer = 0 To _items.Length - 1
Console.WriteLine(_items(i))
Next
End Sub
Public Shared Operator +(a As Vector(Of T), b As Vector(Of T)) As Vector(Of T)
Dim retVal As New Vector(Of T)(a.Size)
For i As Integer = 0 To retVal.Size - 1
retVal.SetValue(i, a.GetValue(i) + b.GetValue(i))
Next
Return retVal
End Operator
End Class
Program.vb:
Module Program
Sub Main(args As String())
Dim x As New Vector(Of Double)(3)
x.SetAll(3)
Dim y As New Vector(Of Double)(3)
y.SetAll(2)
Dim z = x + y
z.Print()
End Sub
End Module
and in C#
Vector.cs:
using System.Numerics;
namespace Test
{
public class Vector<T> where T : INumber<T>
{
private T[] _items;
public Vector(int n) {
Array.Resize<T>(ref _items, n);
}
public int Size {
get { return _items.Length; }
}
public T GetValue(int i) {
return _items[i];
}
public void SetValue(int i, T val){
_items[i] = val;
}
public void SetAll(T val) {
for (var i = 0; i < _items.Length; i++) {
_items[i] = val;
}
}
public void Print() {
for (var i = 0; i < _items.Length; i++) {
Console.WriteLine(_items[i]);
}
}
public static Vector<T> operator +(Vector<T> a, Vector<T> b)
{
var retVal = new Vector<T>(a.Size);
for (var i = 0; i < retVal.Size; i++) {
retVal.SetValue(i, a.GetValue(i) + b.GetValue(i));
}
return retVal;
}
}
}
Program.cs:
using Test;
var x = new Vector<Double>(3);
x.SetAll(3);
var y = new Vector<Double>(3);
y.SetAll(2);
var z = x + y;
z.Print();
In each mwe two vectors (of Double) x,y with a length of 3 are created, so that all entries of x are 3 and all entries of y are 2. These vectors are then added together and saved in the vector z.
The C# project compiles without an error and produces follwing output
5
5
5
while the VB.NET project won't compile and throws above mentioned error.
I don't even really understand why the error is thrown in the first place. The type parameter was given the constrain, that it has to implement the interface INumber(Of T), which in return implements the IAdditionOperators(Of T,T,T) interface, which in return exposes the +-operator. I therefore thought, that T should be able to rely on said operator, like it does in C#, but not in VB.NET.
Is that an error on my site or is VB.NET not working correctly in that regard?