Hello,
I want to define a generic class which should accept only nullable
types or reference types.
What's the best way to costrain it?
---------
class MyClass<T>{
...
}
---------
T must be either nullable type or reference type.
int? is ok.
string is ok.
int is not ok.
Thanks in advance.
Sam 8 10683
Well, you can't do it easily - there is no single constraint that would
help here. Is there any way you can split the code out into 2 blocks,
one for class, one for Nullable<T>? You would still need to use
Default<Tfor the "null", since the (class) null-reference and
Nullable<T"null" are IIRC quite different with the compiler making
them look the same(Nullable<Tbeing a struct).
Marc
You can constrain what types your class can be instantiated with by using
the where clause as in:
class MyClass<Twhere T : class
I cannot see an obvious way to constrain the type to being a Nullable type
as int?, Nullable<intetc. all appear to be invalid in the where clause
above!
- Andy
"Sam Kong" <sa********@gmail.comwrote in message
news:11**********************@75g2000cwc.googlegro ups.com...
Hello,
I want to define a generic class which should accept only nullable
types or reference types.
What's the best way to costrain it?
---------
class MyClass<T>{
...
}
---------
T must be either nullable type or reference type.
int? is ok.
string is ok.
int is not ok.
Thanks in advance.
Sam
I've done some more digging and the problem is that Nullable is actually a
struct. Accordingly templates can only be derived from interfaces,
non-sealed CLASSES and types. struct's cannot be used as base classes; full
stop...
You may be able to define your own class which implements the methods in
line with how the Nullable struct operates; it basically adds a boolean to
each type to indicate whether the value has been assigned or not... I cannot
see any reason why
this will not work but you may not be able to use the short hand form; i.e.
type? you may have to use MyType.Nullable<intmyInt... as I would assume
that the short hand form would be bound to System.Nullable (could be wrong
:).
I cannot think of any reason why this will not work but unless I actually
tried to write the code could not guarantee it would be trouble free. I also
cannot think of any reason why Nullable is implemented as a struct aside
from a value type performance angle.
If you wrote your own Nullable class then:
class MyClass<Twhere T : class
Would obviously work with both reference types and your new
MyNameSpace.Nullable class (as it would be a class) the only problem would
be that calling the methods on it would need an is check (i.e. if (t is
MyNameSpace.Nullable)...).
To avoid this you would need to define two classes, one for reference types
and the other for your Nullable type:
class MyRefClass<Twhere T : class
class MyNullableClass<Twhere T : MyNameSpace.Nullable
HTH
- Andy
"Andy Bates" <an**@ussdev.comwrote in message
news:un**************@TK2MSFTNGP05.phx.gbl...
You can constrain what types your class can be instantiated with by using
the where clause as in:
class MyClass<Twhere T : class
I cannot see an obvious way to constrain the type to being a Nullable type
as int?, Nullable<intetc. all appear to be invalid in the where clause
above!
- Andy
"Sam Kong" <sa********@gmail.comwrote in message
news:11**********************@75g2000cwc.googlegro ups.com...
>Hello,
I want to define a generic class which should accept only nullable types or reference types. What's the best way to costrain it?
---------
class MyClass<T>{ ... }
---------
T must be either nullable type or reference type.
int? is ok. string is ok. int is not ok.
Thanks in advance.
Sam
Andy Bates wrote:
I've done some more digging and the problem is that Nullable is actually a
struct. Accordingly templates can only be derived from interfaces,
non-sealed CLASSES and types. struct's cannot be used as base classes; full
stop...
You may be able to define your own class which implements the methods in
line with how the Nullable struct operates; it basically adds a boolean to
each type to indicate whether the value has been assigned or not... I cannot
see any reason why
this will not work but you may not be able to use the short hand form; i.e.
type? you may have to use MyType.Nullable<intmyInt... as I would assume
that the short hand form would be bound to System.Nullable (could be wrong
:).
I cannot think of any reason why this will not work but unless I actually
tried to write the code could not guarantee it would be trouble free. I also
cannot think of any reason why Nullable is implemented as a struct aside
from a value type performance angle.
If you wrote your own Nullable class then:
class MyClass<Twhere T : class
Would obviously work with both reference types and your new
MyNameSpace.Nullable class (as it would be a class) the only problem would
be that calling the methods on it would need an is check (i.e. if (t is
MyNameSpace.Nullable)...).
To avoid this you would need to define two classes, one for reference types
and the other for your Nullable type:
class MyRefClass<Twhere T : class
class MyNullableClass<Twhere T : MyNameSpace.Nullable
HTH
- 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
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<intmb = 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<stringmb = 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
"Sam Kong" <sa********@gmail.comwrote in message
news:11**********************@m79g2000cwm.googlegr oups.com...
>
Andy Bates wrote:
>I've done some more digging and the problem is that Nullable is actually a struct. Accordingly templates can only be derived from interfaces, non-sealed CLASSES and types. struct's cannot be used as base classes; full stop...
You may be able to define your own class which implements the methods in line with how the Nullable struct operates; it basically adds a boolean to each type to indicate whether the value has been assigned or not... I cannot see any reason why this will not work but you may not be able to use the short hand form; i.e. type? you may have to use MyType.Nullable<intmyInt... as I would assume that the short hand form would be bound to System.Nullable (could be wrong :).
I cannot think of any reason why this will not work but unless I actually tried to write the code could not guarantee it would be trouble free. I also cannot think of any reason why Nullable is implemented as a struct aside from a value type performance angle.
If you wrote your own Nullable class then:
class MyClass<Twhere T : class
Would obviously work with both reference types and your new MyNameSpace.Nullable class (as it would be a class) the only problem would be that calling the methods on it would need an is check (i.e. if (t is MyNameSpace.Nullable)...).
To avoid this you would need to define two classes, one for reference types and the other for your Nullable type:
class MyRefClass<Twhere T : class class MyNullableClass<Twhere T : MyNameSpace.Nullable
HTH
- 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
Hi Andy,
Andy Bates wrote:
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<intmb = 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<stringmb = 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.
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
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
"Sam Kong" <sa********@gmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
Hi Andy,
Andy Bates wrote:
>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<intmb = 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<stringmb = 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.
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 wrote:
Easy to correct the compilation error, change the line:
t[x, y] = null; //Compilation Error!!!
to
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Keith R |
last post by:
Currently, generic types are not CLS compliant. This puts library authors in
a quandry who are faced with three bad alternatives:
1. CLS Compliance but no generics,
2. Using generic types but...
|
by: Wiktor Zychla |
last post by:
I've read several documents about upcoming C# generics and I still cannot
understand one thing.
Would it be valid to write a code like this:
class SomeClass
{
public void AMethod<T>(T a, T...
|
by: Andreas Huber |
last post by:
What follows is a discussion of my experience with .NET generics & the
..NET framework (as implemented in the Visual Studio 2005 Beta 1),
which leads to questions as to why certain things are the...
|
by: Marshal |
last post by:
///////////////////////////////////////////////////////////////////////////////////////////////
/// CONSTRAINTS ON GENERICS
////////////////////////////////////////////////////
public class...
|
by: Dave Booker |
last post by:
Make a template of a template:
public class A<T>
{
A(string s){}
}
public class D<Tobject, Tclass> :
where Tobject : Object
|
by: herpers |
last post by:
Hello,
I probably don't see the obvious, but maybe you can help me out of this
mess.
The following is my problem:
I created two classes NormDistribution and DiscDistribution. Both
classes...
|
by: Dan Holmes |
last post by:
I have a class that i need a constraint of int, string, float or bool. I
have tried the following but can't make VS accept it. I read the docs
and they showed that any value type can be used...
|
by: Joe Bloggs |
last post by:
Hi,
compiling the following code:
public class App
{
static void Main()
{
int? x = 5;
bool? i = null;
|
by: Tony Johansson |
last post by:
Hello!
Is it possible to declare existing .net generics to have nullable types(for
example type int? ) ?
If the answer on the previous question is yes then I assume that you can
also define...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
| |