If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Re: Pointers - Unsafe

You don't need to use pointers - in C# there are two kinds of types: (1) value types (structs), which are passed around by value, and (2) reference types (classes), instances of which are really references to objects (garbage collected pointers of sort), and are thus effectively passed by reference. Basically, class instances behave akin to C++ pointers, except you don't have to delete them manually, and you're not allowed to do pointer arithmetic.

So, you only need to declare it this way:Node next;
// or
Node next = null;

And then when you add a node, you simply write:next = node;

It essentially makes next point to a different object. You continue to use the member access operator (".") as usual.

Re: Pointers - Unsafe

CSharp uses the unsafe keyword as you know to allow you to use pointers. Unsafe code is very C-Like. I believe the closest you can get to a pointer to a user defined class is a pointer to a struct. This is done to allow inter-op with Win32 and other external C/C++ libraries and memory mapped devices. Other than that, you can make pointers to the built in types, that are also classes.

Re: Pointers - Unsafe

If you have an interop scenario, you might need to use pointers and "unsafe" blocks, but, IMO, if you're rewriting code to C#, then, with reference types available, there's really no need for pointers.

Re: Pointers - Unsafe

Sorry, just a question: when you say "ref"-s, did you use ref method parameters or did you mean reference types? If you used ref parameters, there's no need for that either.
If that's the case, I'll explain about the ref later.

What will the value of the original object be when the methods return? To answer that question, you must understand the distinction which C# makes between value types (structs) and reference types (classes). All the fundamental types (byte, int, long, float, double, bool...), except for string, are value types. They are passed around by value by default. String type is a reference type, but is specific in that it's, by design, immutable. That is, when you assign a new string to a variable, it's not the contents of the string objects that changes, but the whole object itself gets replaced. (This enables the language to share same string literals among string variables.) Now, for the code above, all of the variables are local copies, so replacing them will not have any effect on the original. So, the integer will not change, the original string will not be replaced, and the Element object (a reference type) will not be replaced, but it will be mutated (changed internally), and it's Value property will be "The Old New Thing".
It's like when you pass a pointer to an object in C++: a local copy of the pointer is made, but it still points to the same object, so you can modify that object.

What happens now?
For value types, it's straightforward - the ref keyword forces them to be passed by reference. For reference types, the reference itself is passed by reference - analogous to a C++ pointer being passed by reference. This means that you can now make it point to an entirely different object. So, after each of the methods returns, the original integer will be changed, the original string variable will point to a new string, and the original element variable will point to a new object, with the Value property set to "New!".

Code:

Originals
n: 5
s: STRING
e: OLD
Using ref
n: -5
s: string
e: New!

You can try calling these methods in a console application, in the Main() method, and see for yourself. Something like this:

P.S. In the IDE, you can discover if a type is a value type or a reference type by hovering a mouse over a type name and looking if it says struct or class. You can also rely on the MSDN documentation.

If you want to do it that way, then you must use the ref keyword, because, as I said, string is an immutable type. (There's also a mutable variant, called StringBuilder.) So, xy="hi" does not modify the original string object, it actually assigns a completely different object to the variable (read the post above for more detail). But if you had a regular, mutable object, such is, say, a Button (Win Forms), then this would work:

void Change(Button btn)
{
btn = new Button(); // Trying to replace the original object, which is what actually happens with strings
btn.Text = "Hi"; // At this point, btn has nothing to do with the btn that was originally passed here
}
Button b = new Button();
b.Text = "Hello";
Change(b);
//now, it's still: b.Text == "Hello"';

If you have a linked list of elements which contain strings, then you can write an Add() or an Insert(), or a Replace() method without using the ref keyword:

The string, being a class, is passed as a reference to the original string object (analogous to a C++ pointer). In the case of the replace method, you can simply set the internal member variable using "someVar = item", and it will point to the original object.

Basically, if it's a class, it behaves a lot like a pointer, if it's a struct, is just passed by value.

Re: Pointers - Unsafe

There are 2 major problems with that.
First, this doesn't work because although you assign str to the sRef variable, you are simply making it point to the same object. sRef is still a different variable. What's passed by reference to the function is str, so only assigning something to str will affect the original variable.

Now, when you tried assigning str = sRef in the constructor, you did change to what the original variable points to, and if it was an object of a mutable type, the code in bOK_Click would affect it. Note that sRef and str are still different variables pointing to the same object, but this can change.
And, as string is immutable, it does change in the click event handler, which is pretty much is equivalent to:

Code:

private void bOK_Click(object sender, EventArgs e)
{
sRef = new String("Whatever"); // sRef and str no longer point to the same object!
}

The second problem is that, even if the code worked, it breaks encapsulation - it tries to modify internal data of a different class, and that is not a good thing.

The proper way to do it is to define a suitable public interface (by providing a set of public methods and/or properties) on the SaveQueryAs class, which can be used to retrieve the string object (or any other data).
For example, take OpenFileDialog: once the user selects a file and closes the dialog, the form that has shown the dialog window can retrieve the path via the FileName property of the OpenFileDialog class.

So, similarly, define a public property on the SaveQueryAs class; you can name it UserInput, or some other name you think is adequate, and then simply set the value of that property inside the bOK_Click handler.

Then, when the SaveQueryAs dialog is closed, and the control flow returns to the bSave_Click method in Form1, you can simply do:str = save.UserInput;