简体   繁体   中英

Passing a generic pointer to a method in c#

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!

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:

  1. C# and .NET conventions dictate that all public members (methods, properties, fields, etc) should have TitleCase, not camelCase (ie ensure the first letter is capitalised).
  2. Trivial getter and setter methods are discouraged, used Properties instead (though I note you cannot use ref arguments with properties).
  3. You're getting your error because the type of intPointer is not int , but your class GenericPointer<int> .

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM