typesafe ints --- How????

  • Thread starter Thread starter CSharpNewbie
  • Start date Start date
C

CSharpNewbie

Hi

I would like (or a least think I would like to) define a wrapper class
for an int so as to make it type safe. I know this means converting a
value type to a reference type - its not that performance sensitive.

How do I write a class that wraps the integer nicely and is something
other than Object?. For example, I have written:

public class DBSchemaID
{
private int schemaID=0;


public N2KDBSchemaID(int schemaIDIn)
{
schemaID=schemaIDIn;
}

public int SchemaID
{
get{return schemaID;}
set{schemaID=value;}
}
}

So now how can I make it act as an int in the when used as an array
entry? For example:

DBSchemaID schemaID=new DBSchemaID(4);
schemaObj=SchemaArray[schemaID];

Is some sort of implict conversion to int (like ToString()) possible.
Also can one override the operators == and >= etc.

Can this be done? Am I crazy for wanting to do it? How else could you
make sure that the parameters of a method call are type safe. In other
words, if a method is GetSchemaDBName(int schemaID) any int could be
handed in. If the method is GetSchemaDBName(DBSchemaID schemaID) then
I am being a bit stricter and safer. Is it reasonable to want to do
this?

Just being allowed to derive from Int32 would do everything necessary.

What the best way of doing this sort of thing? Any advice appreciated
- I am new to this.

Cheers
OldNewbie
 
the simplest and type safe i cud like to suggest in this case is something
like the following

public enum DBSchemaType {
NT2K,
XP
}

public class DBSchema
{
//...
public GetSchema(DBSchemaType schemaType) {
//enum is type safe cuz otherwise, the code
//wont even compile
}
//...
}
 
On Mon, 7 Nov 2005 04:06:10 -0800, Ashura

Hi Ashure

I'm not sure this would do it. In my case the int I wish to wrap
really is an int. It will eventually be an array index and could have
a value of 100, 10,000 or a million.

I may be mistaken, (I'm new to C#) and I may have misunderstood you
but I don't think I can define a value in the enum for every possible
int.

Cheers
ON
 
enum data type is an integer by itself

say
public enum DBSchemaType {
NT2K = 0,
XP = 1
}

and if ya do the follwoing

DBSchemaType schemaType = DBSchemaType.NT2K;
int typeInt = Convert.ToInt32(schemaType);
//NOW typeInt = 0
 
Hi,



CSharpNewbie said:
Hi

I would like (or a least think I would like to) define a wrapper class
for an int so as to make it type safe.

What you mena with "type safe" ?

DBSchemaID schemaID=new DBSchemaID(4);
schemaObj=SchemaArray[schemaID];

What you gain with that?
Is some sort of implict conversion to int (like ToString()) possible.
ToString() is not implicit , in fact is not even explicit nor a conversion
, ToString() is a method !!!

To answer your question, yes, there is, look into the C# help the the
implicit keyword.


I think you need to rethink what you want first.



cheers,
 
Hi,



CSharpNewbie said:
Hi

I would like (or a least think I would like to) define a wrapper class
for an int so as to make it type safe.

What you mena with "type safe" ?

DBSchemaID schemaID=new DBSchemaID(4);
schemaObj=SchemaArray[schemaID];

What you gain with that?

Hi Ignacio

Well, I'm pretty new as this so to be honest I am not totally sure
what I want.

The problem is that I have arrays of object types lets say they are
ObjX [] XArray = new ObjX[1000];
ObjY [] YArray = new ObjY[10000];
ObjZ [] ZArray = new ObjZ[100000];

These arrays are sparsely populated. There may or may not be an object
in any specific position. The position in the array essentially forms
a quick access "ID" for the object. This ID is used a lot. I pass this
ID into various member functions which perform operations on the
arrays (and the objects contained in the arrays). Since I pass this ID
around I was thinking that I should probably make it an "Object". That
way it would represent a ObjX ID or an ObjY ID. An ObjXID (essentially
an index into the XArray) passed in to a function DoSomething(ObjYID
foo) would generate a compile (or runtime) error rather than just
doing something spurious. Once inside the function they would act just
as an int did. The ability to inherit from int would do this nicely:
i.e.

public class ObjXID : int32 {} // but you can't do this

Thats what I mean by type safe. If I'm flinging various array indexes
around I thought it might be nice to make sure that they actually were
what they were supposed to be instead of a generic int.

I'm inexperienced - so this may be an inappropriate use of the
language. All advice cheerfully received.

Cheers
Newbie
 
Hi,


These arrays are sparsely populated. There may or may not be an object
in any specific position. The position in the array essentially forms
a quick access "ID" for the object. This ID is used a lot. I pass this
ID into various member functions which perform operations on the
arrays (and the objects contained in the arrays).


Why not use a Hashtable ?

Or even create your own strong typed collection

Having an array sparsely populated is not a good idea


cheers,
 
Ignacio Machin ( .NET/ C# MVP ) said:
Why not use a Hashtable ?


I second Ignacio's choice.

A sparce array of objects would need to be large enough to keep references
(pointers?) to each of the objects, whether they existed or not. This could
potentially suck up lots of memory (not to mention difficult to resize).

Scott
 
I had a similar thought to your own, and here is how I resolved the
problem.

Wherever possible, pass object references around, not IDs. Inside your
code, you don't want to be "flinging spurious array indices around" for
precisely the reasons you mentioned: because the client code needs to
know how to use those array indices to get the relevant object. I
decided that it was far better to pass an object reference around. That
way client code has the actual object, not just a name for it.

I then built a bit of structure to help support this sort of thing.

First, I created an interface called IKeyed:

public interface IKeyed
{
public string PrimaryKey { get; }
}

The primary key doesn't need to be a string; it could be an int
instead. Now every business object implements IKeyed, and knows its own
key. Then I built a class, SelfKeyedCollection, that accepted IKeyed
objects. Since each object knows its own key, the SelfKeyedCollection
just needs the object in order to add it:

public void Add(IKeyed obj) ...

Inside the SelfKeyedCollection I used a Hashtable to store the items.

Finally, each business object declared a static method:

public static string PrimaryKey(...)

that allows outside callers to construct a primary key given qualities
of the object. (Your version might return int, not string). So now, I
can pass around business objects (which know their own keys),
collections of business objects (which can be strongly typed), and
clients can find a business object in a collection by constructing a
primary key:

BObj myBusinessObject = keyedCollection[BObj.PrimaryKey(company,
stockCode)];

In the end, passing about the objects themselves turned out to be much
better than passing around IDs.
 
Hi Bruce

Thanks very much for this post. V interesting - I will probably
implement something like this. Much appreciated you sharing it with
me.

Cheers
Newbie
 
Sorry... one correction.

Each business object declares a static method:

public static string BuildPrimaryKey(...)

so you would say

BObj myBusinessObject = keyedCollection[BObj.BuildPrimaryKey(company,
stockCode)];

not "PrimaryKey", since the business object already implements the
IKeyed method and so has an instance property named "PrimaryKey". The
compiler won't let you have an instance property and a static method
with the same name, so your static method for building primary keys
from scratch needs a different name.

Sorry for the typo.
 
Back
Top