|
-
March 26th, 2008, 02:48 PM
#1
Generic Collections
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.
Code:
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
-
March 26th, 2008, 03:04 PM
#2
Re: Generic Collections
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.
Code:
public class IntOperation : IBinaryOperations< int >
{
// implement add/subtract etc here
}
As you can see, this isn't very pretty.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
March 26th, 2008, 03:28 PM
#3
Re: Generic Collections
 Originally Posted by Mutant_Fruit
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.
Code:
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:
Code:
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
-
March 26th, 2008, 03:41 PM
#4
Re: Generic Collections
 Originally Posted by S__B
But then how can I combine them to get something like:
Code:
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.
www.monotorrent.com For all your .NET bittorrent needs
NOTE: My code snippets are just snippets. They demonstrate an idea which can be adapted by you to solve your problem. They are not 100% complete and fully functional solutions equipped with error handling.
-
March 29th, 2008, 03:46 PM
#5
Re: Generic Collections
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.
 Jonny Poet
To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
If anyone felt he has got help, show it in rating the post.
Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
My latest articles :
Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7
-
March 30th, 2008, 06:26 AM
#6
Re: Generic Collections
Whats about the following
Code:
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
 Jonny Poet
To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
If anyone felt he has got help, show it in rating the post.
Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
My latest articles :
Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|