Reputation: 427
I have created a generic type to act as a pointer so that I can pass by reference. (Perhaps there is a much more simple way of doing this but I want to stress that I am doing this to learn more about generics and passing by reference, not the most efficient way of completing the task, if that makes sense.)
Here is the code I wrote for the generic type
class GenericPointer<T> {
public T item;
public void setItem(T i){ item = i; }
public T getItem(){ return item; }
}
In my program I have created an instance of this type called 'intPointer'. The value 143 is arbitrary.
GenericPointer<int> intPointer = new GenericPointer<int>();
intPointer.setItem(143);
Console.WriteLine(intPointer.getItem());
The above code runs properly, setting and returning the value 143.
I now want to pass this 'intPointer' to a method that increments it and then prints the value again.
So I wrote a method called addone()
public void addone(int i) { i ++; }
Now I want to make the following calls (remembering that I already set the value to 143):
Console.WriteLine(intPointer.getItem());
addone(intPointer);
Console.WriteLine(intPointer.getItem());
What I was expecting to see was 143 then 144 however I get the following errors:
The best overloaded method match for 'Notes.Program.addone(int)' has some invalid arguments
and:
cannot convert from 'Notes.GenericPointer<int>' to 'int'
Any help would be greatly appreciated!
Upvotes: 2
Views: 1230
Reputation: 2074
While GenericPointer is wrapping an int, it is not actually an int so it cannot be treated as one. It has properties that are an int.
Imagine if GenericPointer wrapped a string. What would AddOne do to that.
You can act on the properties of the class but not treat the entire class as its generic type.
It would be possible to write an AddOne method that took a Generic Pointer argument and then inspected it for intyness and then added one to the internal item if it was an int. I am sure that is not a good idea.
What are you really trying to achieve with this GenericPointer?
Upvotes: 1
Reputation: 9089
If you want parameters to be reference if they are a value type (string, int, bool, etc.) then make your parameter like this:
public void addone(ref int i)
{
i++;
}
Then call the method like so:
addone(ref variableInt);
You can also look at this in order to see how to make your classes work as a specific type.
Upvotes: 0
Reputation: 155568
I'll begin by correcting some of your terminology: you're not using pointers. C# does support pointers, but using the unsafe
keyword, and they are real pointers (as in, integer memory addresses you can directly manipulate). The code you written is just an example of a boxed object.
.NET supports boxing already, by casting to Object
; however it isn't recommended nor needed because the ref
keyword solves the problem you're trying to "fix".
Use the ref
keyword to describe a value-type parameter that should be passed by-reference instead of by-value. All other semantics remain the same, like so:
void Foo() {
int x = 123;
Bar(ref x);
Console.Write( x ); // prints "124".
}
void Bar(ref int x) {
x++;
}
I have a few other notes:
ref
arguments with properties).intPointer
is not int
, but your class GenericPointer<int>
.Upvotes: 6