:).
> I've done some more digging and the problem is that Nullable is actually a
> struct. Accordingly templates can only be derived from interfaces,
[quoted text clipped - 33 lines]
>
> - Andy
Thank you for your kind answer.
Actually I was trying to make a generic class like this.
class Board<T>{
T[,] cells;
...
}
Board instances holds some 2D array of a type.
You may think of it as Sudoku board.
But I wanted to make it more generic so that strings or numbers can be
contained (not the same time though).
So it will be like string[,] or int[,].
But for empty cells, I want to use null instead of 0.(0 doesn't always
mean empty)
So it will be string[,] or int?[,].
But I couldn't find a way to define that way.
If I don't define such constraint, I can't set null to a cell like
cells[0, 0] = null;.
The compiler would complain that cells[0,0] might be a value type.
For now, I just made it for int? only.
Thanks.
Sam
Andy Bates - 30 Aug 2006 08:14 GMT
Hi -
Okay; I'm not sure that you need to place a constraint on the generic as the
compiler will do all the work for you. Consider:
class MyBoard<T>
{
T[,] t;
public MyBoard(int r, int c)
{
this.t = new T[r, c];
}
public T this[int x, int y]
{
get { return this.t[x, y]; }
set { this.t[x, y] = value; }
}
}
I can use this class with any type (either value or reference) and as long
as I'm careful to copy reference values can do things such as:
MyBoard<int> mb = new MyBoard<int>(2, 2);
mb[0, 0] = 2;
mb[1, 1] = null; // *Compiler error*
int a = mb[0, 0]; // Should be 2.
MyBoard<int?> mb = new MyBoard<int?>(2, 2);
mb[0, 0] = 2;
mb[1, 1] = null;
int? a = mb[1, 1]; // Should be null.
MyBoard<string> mb = new MyBoard<string>(2, 2);
...
The indexer is the key to getting/setting items into the array as this only
works with the type the class is expecting.
- Andy
>> I've done some more digging and the problem is that Nullable is actually
>> a
[quoted text clipped - 69 lines]
>
> Sam
Sam Kong - 30 Aug 2006 23:15 GMT
Hi Andy,
> Hi -
>
[quoted text clipped - 35 lines]
> The indexer is the key to getting/setting items into the array as this only
> works with the type the class is expecting.
Yes, that works.
However, I can't assign null to the array in MyBoard class.
Let's say, you want to reset the board, you might do
public void Reset(){
for(int x = 0; x < t.GetLength(0); x++)
for(int y = 0; y < t.GetLength(1); y++)
t[x, y] = null; //Compilation Error!!!
}
Well, I can reset it outside the board class.
But that's not a very good design, IMHO.
Any idea?
Thanks.
Sam
Andy Bates - 31 Aug 2006 08:12 GMT
Easy to correct the compilation error, change the line:
t[x, y] = null; //Compilation Error!!!
to
t[x, y] = default(T);
This will create an appropriate empty value. For reference types and
nullable types it's null, for value types it's 0 and for structs it's a copy
of the struct with each field to to 0.
Information on this can be found here:
http://msdn2.microsoft.com/en-us/library/xwth0h0d.aspx
That keeps the class nicely encapsulated and resolves the problem that you
are getting instantiating your generic class with value types and structs.
We got there in the end!
- Andy
> Hi Andy,
>
[quoted text clipped - 58 lines]
>
> Sam
Sam Kong - 31 Aug 2006 16:46 GMT
> Easy to correct the compilation error, change the line:
>
[quoted text clipped - 3 lines]
>
> t[x, y] = default(T);
Thank you very much Andy.
Now I will modify my Board class with that.
You're really helping.
Thanks again.
Sam