alternatives to unboxing..

  • Thread starter =?iso-8859-1?B?Z/ZraGFu?=
  • Start date
?

=?iso-8859-1?B?Z/ZraGFu?=

Hi!
I fear this question might be too basic, however being a c++ veteran I
have trouble to get a good desing in c# running.

// a base class
class Vector{};
// inherited class
class VectorChild:Vector{};
class VectorChildChild:VectorChild{};

// some other class
class A
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b) {
// ***********************
// my ugly solution....
// ***********************
if (typeof(Vector) == a.GetType() )
vectorfun( (Vector) a , (Vector) b); // unboxing to Vector
if (typeof(VectorChild) == a.GetType() )
vectorfun( (VectorChild) a , (VectorChild) b); // unboxing to
VectorChild
if (typeof(VectorChildChild) == a.GetType() )
vectorfun( (VectorChildChild) a , (VectorChildChild) b); //
unboxing to VectorChildChild
// ***********************
// ***********************
}
}

I would like to call the "fun" member of an instance of A
using Vector instances and VectorChild instances.

However, sofar I have to explicitly deal with any possible type using
the
if (typeof () == GetType)
lines...

Even if explictly define that VectorChild can be casted into Vector...
( which seems to be ridicilous since its a child) I have to deal with
objects in the ugly way as shown above.
What is the right thing to do?

In C++ the compiler is able to automatically cast down... How can I
achieve this behaviour with
C#?

Unfortunately I have to stick with the object type since my objects (of
arbitrary type) are stored in a HashTable.


I am a totally newbie to c# so excuses if I miss some fundamental
point...
which you guys hopefully tell me...


Thanks for any comments

gökhan
 
J

Joanna Carter [TeamB]

"gökhan" <[email protected]> a écrit dans le message de (e-mail address removed)...

If you are dealing with reference types, then you are not unboxing, you are
simply casting.

// a base class
class Vector{};
// inherited class
class VectorChild:Vector{};
class VectorChildChild:VectorChild{};

// some other class
class A
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b) {
// ***********************
// my ugly solution....
// ***********************
if (typeof(Vector) == a.GetType() )
vectorfun( (Vector) a , (Vector) b); // unboxing to Vector
if (typeof(VectorChild) == a.GetType() )
vectorfun( (VectorChild) a , (VectorChild) b); // unboxing to
VectorChild
if (typeof(VectorChildChild) == a.GetType() )
vectorfun( (VectorChildChild) a , (VectorChildChild) b); //
unboxing to VectorChildChild
// ***********************
// ***********************
}
}

I would like to call the "fun" member of an instance of A
using Vector instances and VectorChild instances.

Then why have you got a method fun that takes objects, why not pass the
Vector/derivatives to the strongly typed method ?

public void vectorfun(Vector a,Vector b){}

....wil take any Vector, VectorChild or VectorChildChild object.

Joanna
 
S

Saad Rehmani

gökhan said:
<snip>
Unfortunately I have to stick with the object type since my objects
(of arbitrary type) are stored in a HashTable.

Just an FYI: C# 2.0 has functionality similar to STL. A search on generic
should give you some decent hits.

A couple of things:

1. You should be able to replace 'typeof(Vector) == a.GetType()' with 'a
is Vector', if you do that, you'll have to check for the subclass before
you check for the parent

2. '(VectorChild) a' is not really boxing, its a cast. You also might want
to read up on why you might use 'a as VectorChild' instead
 
?

=?iso-8859-1?B?Z/ZraGFu?=

Joanna said:
"gökhan" <[email protected]> a écrit dans le message de (e-mail address removed)...

If you are dealing with reference types, then you are not unboxing, you are
simply casting.

// a base class
class Vector{};
// inherited class
class VectorChild:Vector{};
class VectorChildChild:VectorChild{};

// some other class
class A
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b) {
// ***********************
// my ugly solution....
// ***********************
if (typeof(Vector) == a.GetType() )
vectorfun( (Vector) a , (Vector) b); // unboxing to Vector
if (typeof(VectorChild) == a.GetType() )
vectorfun( (VectorChild) a , (VectorChild) b); // unboxing to
VectorChild
if (typeof(VectorChildChild) == a.GetType() )
vectorfun( (VectorChildChild) a , (VectorChildChild) b); //
unboxing to VectorChildChild
// ***********************
// ***********************
}
}

I would like to call the "fun" member of an instance of A
using Vector instances and VectorChild instances.

Then why have you got a method fun that takes objects, why not pass the
Vector/derivatives to the strongly typed method ?

public void vectorfun(Vector a,Vector b){}

...wil take any Vector, VectorChild or VectorChildChild object.

Joanna


class A{
public virtual void fun(object a,object b) {}

}
class A0:A{
public override void fun(object a,object b) {}

}
A.fun(a,b) -> problem !

Because I am calling some base class.. That is obviously not my
problem.
 
?

=?iso-8859-1?B?Z/ZraGFu?=

Joanna said:
"gökhan" <[email protected]> a écrit dans le message de (e-mail address removed)...

If you are dealing with reference types, then you are not unboxing, you are
simply casting.

// a base class
class Vector{};
// inherited class
class VectorChild:Vector{};
class VectorChildChild:VectorChild{};

// some other class
class A
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b) {
// ***********************
// my ugly solution....
// ***********************
if (typeof(Vector) == a.GetType() )
vectorfun( (Vector) a , (Vector) b); // unboxing to Vector
if (typeof(VectorChild) == a.GetType() )
vectorfun( (VectorChild) a , (VectorChild) b); // unboxing to
VectorChild
if (typeof(VectorChildChild) == a.GetType() )
vectorfun( (VectorChildChild) a , (VectorChildChild) b); //
unboxing to VectorChildChild
// ***********************
// ***********************
}
}

I would like to call the "fun" member of an instance of A
using Vector instances and VectorChild instances.

Then why have you got a method fun that takes objects, why not pass the
Vector/derivatives to the strongly typed method ?

public void vectorfun(Vector a,Vector b){}

...wil take any Vector, VectorChild or VectorChildChild object.

Joanna


class A{
public virtual void fun(object a,object b) {}

}
class A0:A{
public override void fun(object a,object b) {}

}
A.fun(a,b) -> problem !

Because I am calling some base class.. That is obviously not my
problem.
 
?

=?iso-8859-1?B?Z/ZraGFu?=

Saad said:
Just an FYI: C# 2.0 has functionality similar to STL. A search on generic
should give you some decent hits.

A couple of things:

1. You should be able to replace 'typeof(Vector) == a.GetType()' with'a
is Vector', if you do that, you'll have to check for the subclass before
you check for the parent

2. '(VectorChild) a' is not really boxing, its a cast. You also might want
to read up on why you might use 'a as VectorChild' instead
Hi! Thanks.. I am reading about generics.

What would I gain using "is/as" since I would still need to do checks
in my code before
casting/unboxing.. Is there now way such that
I could unbox to Vector although it was boxed to VectorChild or
VectorChildChild ?
 
J

james.curran

Much is unclear about your code. First of all, How many vectorfun
methods are there? If there is just one, in Vector, then your code is
accomplishing nothing. The objects are being cast back to Vectors
during the function call.
However, if there is a vectorfun method in each class, then why are you
fight OO design?

Replace
static void vectorfun(Vector a, Vector b)
with
virtual void vectorfun(Vector b) // a is now the "this" reference.

Then fun() becomes just:
public override void fun(Vector a,Vector b) {
{
a.vectorfun(b);
}
 
?

=?iso-8859-1?B?Z/ZraGFu?=

Much is unclear about your code. First of all, How many vectorfun
methods are there? If there is just one, in Vector, then your code is
accomplishing nothing. The objects are being cast back to Vectors
during the function call.
However, if there is a vectorfun method in each class, then why are you
fight OO design?

Replace
static void vectorfun(Vector a, Vector b)
with
virtual void vectorfun(Vector b) // a is now the "this" reference.

Then fun() becomes just:
public override void fun(Vector a,Vector b) {
{
a.vectorfun(b);
}

Hi! Thanks for your reply. There wasnt any static in my code and I
really do not fight OO Design. ( I am an admirer of it...)
The root to my problem is that unboxing is done to the original type
and the compiler
jsut does not do any automatic casting.

I have to handle objects due other design constraints, so the whole
issue is the
"right" unboxing to the target type. my implementations need to react
different regarding the boxed type.
 
J

Joanna Carter [TeamB]

"gökhan" <[email protected]> a écrit dans le message de (e-mail address removed)...

| I have to handle objects due other design constraints, so the whole
| issue is the
| "right" unboxing to the target type. my implementations need to react
| different regarding the boxed type.

The code you are posting is not a clear example of what you are trying to
achieve.

And you are *not* repeat *not* unboxing, you are only casting.

Boxing only concerns value types, not reference types like your own classes.

Joanna
 
B

Bruce Wood

gökhan said:
Hi!
I fear this question might be too basic, however being a c++ veteran I
have trouble to get a good desing in c# running.

// a base class
class Vector{};
// inherited class
class VectorChild:Vector{};
class VectorChildChild:VectorChild{};

// some other class
class A
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b) {
// ***********************
// my ugly solution....
// ***********************
if (typeof(Vector) == a.GetType() )
vectorfun( (Vector) a , (Vector) b); // unboxing to Vector
if (typeof(VectorChild) == a.GetType() )
vectorfun( (VectorChild) a , (VectorChild) b); // unboxing to
VectorChild
if (typeof(VectorChildChild) == a.GetType() )
vectorfun( (VectorChildChild) a , (VectorChildChild) b); //
unboxing to VectorChildChild
// ***********************
// ***********************
}
}

I would like to call the "fun" member of an instance of A
using Vector instances and VectorChild instances.

However, sofar I have to explicitly deal with any possible type using
the
if (typeof () == GetType)
lines...

Even if explictly define that VectorChild can be casted into Vector...
( which seems to be ridicilous since its a child) I have to deal with
objects in the ugly way as shown above.
What is the right thing to do?

In C++ the compiler is able to automatically cast down... How can I
achieve this behaviour with
C#?

Unfortunately I have to stick with the object type since my objects (of
arbitrary type) are stored in a HashTable.


I am a totally newbie to c# so excuses if I miss some fundamental
point...
which you guys hopefully tell me...


Thanks for any comments

gökhan

It is not at all clear from the sample you gave what the larger problem
is. You've given a small sample of code and asked how to fix it, but
the sample already has many assumptions built into it.

I think that we need to understand the larger context in which the code
is being used in order to understand how to best implement the solution
in C#.

For example, what is the "A" class used for?

You state that "fun" must take objects because you are "using a
Hashtable" of "arbitrary objects". Are the objects _really_ aribtrary?
If they are, what do you do with objects that are not Vector,
VectorChild, or VectorChildChild? Or do you mean that the Hashtable can
hold any of the types that "fun" can process (but not, for example, a
System.IO.StreamWriter or a System.Windows.Forms.Form, or some other
randomly chosen object)?

How does your use of a Hashtable relate to the code sample you
supplied?

What does "fun" really intended to do (you only showed the part that
distinguishes between the Vector types)?

Maybe there's a better way to architect what you're doing, but we can't
really say because we don't know the context in which all of this is
happening.
 
B

Bjorn Abelli

gökhan said:
I fear this question might be too basic, however being
a c++ veteran I have trouble to get a good desing in c# running.

I fear you have left out some crucial information in your example, which can
make it harder to interpret your problem, however...

As I understand, you forgot to include that "A" also is a subclass of some
other class which you are not in position to modify? Am I right?

class A : SomeExternalClassWithVirtualFunMethod
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b)
{
vectorfun( (Vector) a , (Vector) b);
}
}

The solution above seems to be the most straightforward.
I would like to call the "fun" member of an instance of A
using Vector instances and VectorChild instances.

As VectorChild and VectorChildChild both are subclasses to your Vector,
there's no need to do any other casting than to your Vector.
What is the right thing to do?

If you want to make it "safer" in order to avoid InvalidCastExceptions if a
or b *not* is one of your Vector's subclasses, you can use "as", e.g.:

public override void fun(object a,object b)
{
Vector va = a as Vector;
Vector vb = b as Vector;

if (va != null && vb != null)
{
vectorfun(va , vb);
}
}

http://msdn2.microsoft.com/en-us/library/cscsdfbt(VS.80).aspx
Unfortunately I have to stick with the object type since my
objects (of arbitrary type) are stored in a HashTable.

If they weren't of an "arbitrary type", you could exchange the HashTable
with e.g. a "generic" Dictionary<KeyType, Vector>.


// Bjorn A
 
?

=?iso-8859-1?B?Z/ZraGFu?=

Hi Bjorn!
Thanks to the great hints.

Bjorn Abelli schrieb:


As I understand, you forgot to include that "A" also is a subclass of some
other class which you are not in position to modify? Am I right?

class A : SomeExternalClassWithVirtualFunMethod
{
public void vectorfun(Vector a,Vector b){}

public override void fun(object a,object b)
{
vectorfun( (Vector) a , (Vector) b);
}
}

The solution above seems to be the most straightforward.

Exactly.


As VectorChild and VectorChildChild both are subclasses to your Vector,
there's no need to do any other casting than to your Vector.
The only problem I have is that I need to cast to the _exact_ type
from object.
The code above would lead to an casting exception if the objects are of
form VectorChild,
although it is a child.

public override void fun(object a,object b)
{
Vector va = a as Vector;
Vector vb = b as Vector;

if (va != null && vb != null)
{
vectorfun(va , vb);
}
}



If they weren't of an "arbitrary type", you could exchange the HashTable
with e.g. a "generic" Dictionary<KeyType, Vector>.
That isnt an option, unfortunately.
 
M

Mark Wilden

gökhan said:
The only problem I have is that I need to cast to the _exact_ type
from object.
The code above would lead to an casting exception if the objects are of
form VectorChild, although it is a child.

Really, it wouldn't. Give it a try! A VectorChild is a Vector, just as a
Vector is an object.
 
B

Bjorn Abelli

gökhan said:
Hi Bjorn!
Thanks to the great hints.

You're welcome.
The code above would lead to an casting exception if the objects are of
form VectorChild, although it is a child.

Nope, it wouldn't!

Not if VectorChild really is a subclass to Vector.

Perhaps you only think that you use instances of VectorChild, while they're
something else altogether?

What is the *exact* error message you get?

/// Bjorn A
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top