Reference to a struct inside its definition

A

az.anonymous

Im starting to learn C#, and I made a simple stack class. Inside the
stack class I had the following:

class StackElement
{
object info;
StackElement below;
}

Everything works fine cause "below" is just a reference. But, what if
I want to do it with a struct?. Since struct is a value type, how can
I put a reference to itself inside its declaration? I tried something
like:

struct StackElement
{
object info;
ref StackElement below;
}
and
struct StackElement
{
object info;
StackElement *below;
}

but it didn´t work. So how can I do it?
 
P

Peter Duniho

[...]
struct StackElement
{
object info;
StackElement *below;
}

but it didn´t work. So how can I do it?

I think the latter would work using "unsafe" code? However, if you want
to stick to "safe" C# and a pointer isn't allowed, I think you would
have to allow the struct to be boxed, and use "object" as the type for
the field.

That said, I would suggest that I think if you're dealing with a type
where you feel you need a reference to the type, then the type itself
should be a reference type, not a value type. That means making it a
class instead of a struct.

You didn't ask, but with respect to your specific example, I have a
couple of other things to point out:

* There is already a nice generic Stack<> class in .NET. So your
effort might be useful as a learning exercise (it's certainly raised at
least one interesting learning point here :) ), but do keep in mind the
availability of other options when writing "real" code.

* A stack implementation in general isn't necessarily implemented
as a linked list as you appear to be trying to do here. In fact I would
guess that most implementations are _not_ as a linked list. I'm pretty
sure the generic Stack<> class, for example, uses an array to store the
stack elements, and I'd guess that's a fairly common implementation.

Storing the stack in array, you completely avoid any issues with respect
to having one element refer to another; they are organized simply by
virtue of their order in the array. In fact, if you implement the stack
as a generic class, you can simply make the array contain directly the
elements of the stack, just as the existing Stack<> class does, which
allows you to avoid boxing of value types as long as the stack contains
only elements of the same type.

Pete
 
A

az.anonymous

[...]
structStackElement
{
object info;
StackElement *below;
}
but it didn´t work. So how can I do it?

I think the latter would work using "unsafe" code? However, if you want
to stick to "safe" C# and a pointer isn't allowed, I think you would
have to allow thestructto be boxed, and use "object" as the type for
the field.

That said, I would suggest that I think if you're dealing with a type
where you feel you need a reference to the type, then the typeitself
should be a reference type, not a value type. That means making it a
class instead of astruct.

You didn't ask, but with respect to your specific example, I have a
couple of other things to point out:

* There is already a nice generic Stack<> class in .NET. So your
effort might be useful as a learning exercise (it's certainly raised at
least one interesting learning point here :) ), but do keep in mind the
availability of other options when writing "real" code.

* A stack implementation in general isn't necessarily implemented
as a linked list as you appear to be trying to do here. In fact I would
guess that most implementations are _not_ as a linked list. I'm pretty
sure the generic Stack<> class, for example, uses an array to store the
stack elements, and I'd guess that's a fairly common implementation.

Storing the stack in array, you completely avoid any issues with respect
to having one element refer to another; they are organized simply by
virtue of their order in the array. In fact, if you implement the stack
as a generic class, you can simply make the array contain directly the
elements of the stack, just as the existing Stack<> class does, which
allows you to avoid boxing of value types as long as the stack contains
only elements of the same type.

Pete

Thanks a lot for answering it.
Im coming from C, and I am trying to convert some codes to C# just 4
fun. Since there are many structs pointing to each other and to
theriselves, I was wondering how could I do it in C#. That's why I was
coding this stack.

So, Should I do it using classes only? You said something about
allowing the struct to be boxed. How can I do it, so that I can use an
object type to refer the struct?

What about using this System.IntPtr type?? I don't know what it does,
but maybe it can help me
 
P

Peter Duniho

Thanks a lot for answering it.
Im coming from C, and I am trying to convert some codes to C# just 4
fun. Since there are many structs pointing to each other and to
theriselves, I was wondering how could I do it in C#. That's why I was
coding this stack.

Well, just as that's not a great way to implement a stack in C#, it
wouldn't really be a great way to implement it in C.

But the more general issue here is that you've got a data type that you
expect to be stored as a reference on a regular basis, making it more
appropriate as a reference type than a value type.

It's very important, if you're going to know C#, to understand the
difference between reference types and value types. They look very
similar in the language, but have very specific, different behaviors.

Generally speaking, classes are reference types, while structs and
primitive types are value types.
So, Should I do it using classes only? You said something about
allowing the struct to be boxed. How can I do it, so that I can use an
object type to refer the struct?

The language does it automatically. If you assign a value type to a
variable that's of type object, or pass it as a parameter of type
object, etc. the compiler will generate code that creates an object
instance that contains the value type you've used.

If you later assign that object back to a value type, the compiler will
again generate the code necessary to get the value type data out of the
object instance and copy it to the value type instance.

One thing to keep in mind here is that when the value type is boxed, you
get a whole new instance. If you box the same value instance multiple
times, you get multiple instances, each with a new copy of the value type.

Again, if you need to reference a specific instance of a piece of data,
you really should be using a reference type.
What about using this System.IntPtr type?? I don't know what it does,
but maybe it can help me

Probably not. It is sort of like a "void *", but the issue here is that
you don't have a type that is easily referenced, because it's a value
type. Value types are meant to be passed around intact, not referenced.
You can do thing that will cause them to be referenced, but IMHO it is
better to just use a reference type in the first place, if you want to
be able to reference the data.

Pete
 

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