Hi,
While C# appeared similar to C++ on paper, I have started to struggle learning it. I started off with creating a generic matrix class, but soon simplified the problem to a class doing binary operations.
internal interface IBinaryOperations< T >
{
T Add( T val1, T val2 );
T Subtract( T val1, T val2 );
T Multiply( T val1, T val2 );
T Divide( T val1, T val2 );
}
public class CBinaryOperations< T > : IBinaryOperations< T >
{
public static T Add( T val1, T val2 ) {
return( val1 + val2 ); }
public static T Subtract( T val1, T val2 ) {
return( val1 - val2 ); }
public static T Multiply( T val1, T val2 ) {
return( val1 * val2 ); }
public static T Divide( T val1, T val2 ) {
return( val1 / val2 ); }
}
The problem is that it issues the error "CS0019: Operator '+' cannot be applied to operands of type 'T' and 'T'". Could someone please help?
Thanks
SB
Mutant_Fruit
March 26th, 2008, 03:04 PM
You can't use those maths operators on generic types. It's not supported by the C# specification. You can define the methods like you've done in your interface declaration, but you must implement them for each individal concrete subclass. i.e.
public class IntOperation : IBinaryOperations< int >
{
// implement add/subtract etc here
}
As you can see, this isn't very pretty.
S__B
March 26th, 2008, 03:28 PM
You can't use those maths operators on generic types. It's not supported by the C# specification. You can define the methods like you've done in your interface declaration, but you must implement them for each individal concrete subclass. i.e.
public class IntOperation : IBinaryOperations< int >
{
// implement add/subtract etc here
}
As you can see, this isn't very pretty.
But then how can I combine them to get something like:
class CMatrix< T >
{
private int _m;
private int _n;
private double[,] _data;
public CMatrix< T > Add( ref CMatrix< T > M1, ref CMatrix< T > M2 )
{
for( int i = 0; i < _m; i++ )
{
for( int j = 0; j < _n; j++ )
{
_data[ i, j ] = M1._data[ i, j ] + M2._data[ i, j ];
}
}
return( this );
}
}
Do you mean the only way possible is to have a separate CMatrix for each data type? Isn't this a step backwards when compared to C++?
Thanks
SB
Mutant_Fruit
March 26th, 2008, 03:41 PM
But then how can I combine them to get something like:
class CMatrix< T >
{
private int _m;
private int _n;
private double[,] _data;
public CMatrix< T > Add( ref CMatrix< T > M1, ref CMatrix< T > M2 )
{
for( int i = 0; i < _m; i++ )
{
for( int j = 0; j < _n; j++ )
{
_data[ i, j ] = M1._data[ i, j ] + M2._data[ i, j ];
}
}
return( this );
}
}
You can't.
Do you mean the only way possible is to have a separate CMatrix for each data type? Isn't this a step backwards when compared to C++?
Thanks
SB
Thing is, generics aren't quite as broad as they templates are in C++. This is one of the things you just cannot do cleanly with generics.
JonnyPoet
March 29th, 2008, 03:46 PM
It is impossible in the way you did, but maybe you are able to do some constraints using 'where' for examle mybe you restrict T to be a valueType or you restrict it to be inherited from a specific class. Maybe especially if you restrict it to be a valueType you will be able to do what you want.
JonnyPoet
March 30th, 2008, 06:26 AM
Whats about the following
using System;
using System.Collections.Generic;
using System.Text;
namespace GenericConstraints {
class Program {
static void Main(string[] args) {
Matrix<MyInt> a = new Matrix<MyInt>(2, 3);
Matrix<MyInt> b = new Matrix<MyInt>(2, 3);
b[0, 0] = new MyInt(1);
b[0, 1] = new MyInt(5);
b[0, 2] = new MyInt(7);
b[1, 0] = new MyInt(13);
b[1, 1] = new MyInt(41);
b[1, 2] = new MyInt(8);
Matrix<MyInt> c = new Matrix<MyInt>(2, 3);
c[0, 0] = new MyInt(16);
c[0, 1] = new MyInt(9);
c[0, 2] = new MyInt(13);
c[1, 0] = new MyInt(41);
c[1, 1] = new MyInt(23);
c[1, 2] = new MyInt(11);
a.Add(b, c);
Console.WriteLine("b[0/0] {0} b[0/1] {1} b[0/2] {2} ", b[0, 0].ToString(), b[0, 1].ToString(), b[0, 2].ToString());
Console.WriteLine("c[0/0] {0} c[0/1] {1} c[0/2] {2} ", c[0, 0].ToString(), c[0, 1].ToString(), c[0, 2].ToString());
Console.WriteLine("a[0/0] {0} a[0/1] {1} a[0/2] {2} ", a[0, 0].ToString(), a[0, 1].ToString(), a[0, 2].ToString());
Console.WriteLine("b[1/0] {0} b[1/1] {1} b[1/2] {2} ", b[1, 0].ToString(), b[1, 1].ToString(), b[1, 2].ToString());
Console.WriteLine("c[1/0] {0} c[1/1] {1} c[1/2] {2} ", c[1, 0].ToString(), c[1, 1].ToString(), c[1, 2].ToString());
Console.WriteLine("a[1/0] {0} a[1/1] {1} a[1/2] {2} ", a[1, 0].ToString(), a[1, 1].ToString(), a[1, 2].ToString());
//********************************************************************************************************************
Matrix<MyDouble> f = new Matrix<MyDouble>(2, 3);
Matrix<MyDouble> d = new Matrix<MyDouble>(2, 3);
d[0, 0] = new MyDouble(1.5);
d[0, 1] = new MyDouble(13.3);
d[0, 2] = new MyDouble(7.2);
d[1, 0] = new MyDouble(6.66);
d[1, 1] = new MyDouble(4.25);
d[1, 2] = new MyDouble(8.18);
Matrix<MyDouble> e = new Matrix<MyDouble>(2, 3);
e[0, 0] = new MyDouble(23.12);
e[0, 1] = new MyDouble(46.37);
e[0, 2] = new MyDouble(10.1);
e[1, 0] = new MyDouble(74.89);
e[1, 1] = new MyDouble(3.0);
e[1, 2] = new MyDouble(11.11);
f.Add(d, e);
Console.WriteLine("d[0/0] {0} d[0/1] {1} d[0/2] {2} ", d[0, 0].ToString(), d[0, 1].ToString(), d[0, 2].ToString());
Console.WriteLine("e[0/0] {0} e[0/1] {1} e[0/2] {2} ", e[0, 0].ToString(), e[0, 1].ToString(), e[0, 2].ToString());
Console.WriteLine("f[0/0] {0} f[0/1] {1} f[0/2] {2} ", f[0, 0].ToString(), f[0, 1].ToString(), f[0, 2].ToString());
Console.WriteLine("d[1/0] {0} d[1/1] {1} d[1/2] {2} ", d[1, 0].ToString(), d[1, 1].ToString(), d[1, 2].ToString());
Console.WriteLine("e[1/0] {0} e[1/1] {1} e[1/2] {2} ", e[1, 0].ToString(), e[1, 1].ToString(), e[1, 2].ToString());
Console.WriteLine("f[1/0] {0} f[1/1] {1} f[1/2] {2} ", f[1, 0].ToString(), f[1, 1].ToString(), f[1, 2].ToString());
}
}
public interface IMyParams<T> {
void Add(T b, T c);
string ToString();
}
public class Matrix<T> where T : IMyParams<T> , new()
{
private int _m;
private int _n;
public T[] _data;
private T _result;
public Matrix(int m, int n) {
_m = m;
_n = n;
_data = new T[_m * _n];
}
public T this[int i, int j] {
get {
return _data[i * _n + j];
}
set {
_data[i * _n + j] = value;
}
}
public Matrix<T> Add( Matrix<T> val1, Matrix<T> val2) {
for (int i = 0; i < _m; i++) {
for (int j = 0; j < _n; j++) {
_result = new T();
_result.Add(val1[i, j], val2[i, j]);
_data[i * _n + j] = _result;
}
}
return this;
}
}
public class MyInt : IMyParams<MyInt>{
private int _a;
// Ctors
public MyInt() { }
public MyInt(int a) {
_a = a;
}
// IParams
public virtual void Add(MyInt b, MyInt c) {
_a = b._a + c._a;
}
public override string ToString() {
return _a.ToString();
}
}
public class MyDouble : IMyParams<MyDouble> {
private double _a;
// Ctors
public MyDouble() { }
public MyDouble(double a) {
_a = a;
}
// IParams
public virtual void Add(MyDouble b, MyDouble c) {
_a = b._a + c._a ;
}
public override string ToString(){
return _a.ToString();
}
}
}
I did to different values to test it :wave:
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.