473,386 Members | 1,810 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Generics constraint for nullable or reference types

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

Aug 28 '06 #1
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

Aug 29 '06 #2
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

Aug 29 '06 #3
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



Aug 29 '06 #4

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

Aug 30 '06 #5
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

Aug 30 '06 #6
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

Aug 30 '06 #7
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

Aug 31 '06 #8

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

Aug 31 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
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...
2
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...
17
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...
3
by: Marshal | last post by:
/////////////////////////////////////////////////////////////////////////////////////////////// /// CONSTRAINTS ON GENERICS //////////////////////////////////////////////////// public class...
8
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
11
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...
6
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...
2
by: Joe Bloggs | last post by:
Hi, compiling the following code: public class App { static void Main() { int? x = 5; bool? i = null;
3
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
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...
0
BarryA
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
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...
0
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...
0
marktang
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,...
0
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...
0
jinu1996
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...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.