简体   繁体   English

将通用指针传递给c#中的方法

[英]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'. 在我的程序中,我创建了一个名为“ intPointer”的实例。 The value 143 is arbitrary. 值143是任意的。

GenericPointer<int> intPointer = new GenericPointer<int>();
intPointer.setItem(143);
Console.WriteLine(intPointer.getItem());

The above code runs properly, setting and returning the value 143. 上面的代码运行正常,设置并返回值143。

I now want to pass this 'intPointer' to a method that increments it and then prints the value again. 我现在想将这个'intPointer'传递给一个递增它的方法,然后再次打印该值。

So I wrote a method called addone() 所以我写了一个名为addone()的方法

public void addone(int i) { i ++; }

Now I want to make the following calls (remembering that I already set the value to 143): 现在我想进行以下调用(记住我已经将值设置为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: 我原本希望看到的是143,然后是144,但是出现以下错误:

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). C#确实支持指针,但使用unsafe关键字,它们是真正的指针(如在整数存储器地址中,您可以直接操作)。 The code you written is just an example of a boxed object. 您编写的代码只是装箱对象的示例。

.NET supports boxing already, by casting to Object ; .NET已经通过强制转换为Object来支持装箱; however it isn't recommended nor needed because the ref keyword solves the problem you're trying to "fix". 但是不推荐也不需要它,因为ref关键字解决了你试图“修复”的问题。

Use the ref keyword to describe a value-type parameter that should be passed by-reference instead of by-value. 使用ref关键字来描述应该按引用而不是按值传递的值类型参数。 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). C#和.NET约定规定所有公共成员(方法,属性,字段等)都应该有TitleCase,而不是camelCase(即确保首字母大写)。
  2. Trivial getter and setter methods are discouraged, used Properties instead (though I note you cannot use ref arguments with properties). 不建议使用普通的getter和setter方法,而应使用Properties(尽管我注意到您不能将ref参数与properties一起使用)。
  3. You're getting your error because the type of intPointer is not int , but your class GenericPointer<int> . 由于intPointer的类型不是int ,而是您的类GenericPointer<int>

While GenericPointer is wrapping an int, it is not actually an int so it cannot be treated as one. 虽然GenericPointer包装了一个int,但它实际上并不是一个int,因此它不能被视为一个int。 It has properties that are an int. 它具有int的属性。

Imagine if GenericPointer wrapped a string. 想象一下,如果GenericPointer包裹了一个字符串。 What would AddOne do to that. AddOne会对此做些什么。

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. 可以编写一个采用通用指针参数的AddOne方法,然后检查其是否为整型,如果内部值为int,则将其添加到内部项中。 I am sure that is not a good idea. 我确信这不是一个好主意。

What are you really trying to achieve with this GenericPointer? 你真的想用这个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. 您还可以查看此内容 ,以了解如何使您的类作为特定类型工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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