'ref'问题 [英] 'ref' question

查看:150
本文介绍了'ref'问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



公共类stringtemp

{

字符串k;

public stringtemp(ref String inp)

{

k = inp;

}

public void更改()

{

k = k。移除(0,1);

}

};


String stringtochange = new String(" Hello" .ToCharArray());

stringtemp t = new stringtemp(ref stringtochange);

t.Change();


为什么这里没有将stringtochange更改为''ello''?当我使用ArrayList而不是String尝试类似的样本

时,我的原始变量会被反映出来。

所以我的问题是:我怎样才能确保我在运行引用?

文档说所有类类型都通过引用传递。有人可以详细说明吗?


TIA

解决方案

" Priyesh" < PR ***** @ donotreply.com>写在

新闻:uf ************** @ TK2MSFTNGP15.phx.gbl:

为什么没有改变stringtochange到''ello''在这里?当我尝试使用ArrayList而不是String的类似
样本时,我的原始变量
会被反映出来。所以我的问题是:我怎样才能确保我在参考上运作
?文档说所有类类型都通过
引用传递。有人可以详细说明吗?




字符串 class isn''ta引用类型 - 它是一个值类型,所以在:


public stringtemp(ref String inp)

{

k = inp;

}


即使你正在引用inp,''k = inp''仍然作为一个值完成

赋值。


为了做你想做的事,你必须把''string inp''作为

另一个类的成员,并传递类实例而不是字符串

本身。


-

-mdb


public stringtemp(ref String inp)


表示你​​可以改变inp _in constructor_和

对应的参数变量将在外面改变。


字符串k;


表示什么?它是否说k是对字符串的引用?不,它说,k

是一个字符串。所以,当你说


this.k = inp;


你所说的是,k应该是一样的字符串包含在

inp *"中。既然你没有机会在构造函数中改变in_

_,那么你只需要改变k,但是永远不要inp,

" stringtochange"永远不会改变。


仅仅因为你将一个参数声明为ref并不意味着它的价值是b< b< refness是粘性的,无论它走到哪里都跟着那个字符串值。

现在,如果C#允许你这样说:


公共类stringtemp

{

ref String k;


public stringtemp(ref String inp)

{

this.k = inp;

}

...

}


然后我们可能会有一些东西在这里。然而,ref String k是不是

a有效的现场声明,所以你运气不好。


当你进入Change方法时,事实是 INP"是

最初声明的ref完全无关紧要。在构造函数中它只是相关的



C#和.NET的设计目标之一就是避免使用指针

可能在C和C ++中出现的混乱。这就是为什么你不能宣布支持引用的
变量的原因:它们只是指向另一个名字的指示,并为各种疯狂敞开大门。拿另一个

来看看你的例子,并想一想:


String stringtochange =" Hello";

stringtemp t = new stringtemp(ref stringtochange);

...这里有200行复杂代码...

t.Change();


突然,代码中没有任何警告或任何迹象表明它可能发生,变量stringtochange *魔术*在
调用t.Change()后改变。维护代码有多容易?这就是C#试图避免的事情。

*从技术上讲,这有点谎言。实际上,k是对

字符串的引用,因为字符串在字符串变量中通过引用保存。

但是,inp是对字符串的引用的引用,这是为了更改在调用中传入的参数所需的



正确地说,我应该说在C#中没有办法将k

声明为私有成员,它是对字符串引用的引用,

这是你需要创建的内容你想要的行为

看。但是,为了避免混淆,我改写了一切。在

这种情况​​下,您可以将字符串视为值,即使它们是真正引用的
。出于解释的目的,区别

是无关紧要的。


不是这样。字符串确实是一种参考类型。毕竟,System.String是一个

类,而不是结构。但是,因为字符串是不可变的,所以它们具有非常类似于b $ b的类似语义,因为对字符串的任何更改都会导致在引擎盖下创建完全新的字符串。 ;。在大多数情况下,这会产生一个

字符串表现。表面上好像它是一种价值类型。例如:


myString =" foo" + someOtherString;


....真的会导致编译器发出更像这样的代码:


myString = new String(" ; foo" + someOtherString)


....如果调用者的上下文中存在

,则不会更改原始的myString引用使* *看起来*表现得像一个值类型。

但是,所有传递给方法的传统字符串参数的是

a * reference *到一个字符串,尽管如此。


--BOB


-----原帖-----

来自:mdb; < m_b_r_a_y @ c_t_i_u_s_a__d0t__com>

新闻组:microsoft.public.dotnet.languages.csharp

发送时间:2005年6月1日星期三下午4:09

主题:Re:''ref''问题

" string" class不是引用类型 - 它是一个值类型,所以在:




public class stringtemp
{
String k ;
public stringtemp(ref String inp)
{
k = inp ;
}
public void Change()
{
k = k.Remove(0, 1) ;
}
};

String stringtochange = new String("Hello".ToCharArray()) ;
stringtemp t = new stringtemp(ref stringtochange) ;
t.Change() ;

Why isnt stringtochange changed to ''ello'' here? When I try a similar sample
with an ArrayList instead of a String, my original variable gets reflected.
So my question is: How can i make sure i am operating on a reference?
Documentation says all class types are passed by references. Could someone
elaborate?

TIA


解决方案

"Priyesh" <pr*****@donotreply.com> wrote in
news:uf**************@TK2MSFTNGP15.phx.gbl:

Why isnt stringtochange changed to ''ello'' here? When I try a similar
sample with an ArrayList instead of a String, my original variable
gets reflected. So my question is: How can i make sure i am operating
on a reference? Documentation says all class types are passed by
references. Could someone elaborate?



The "string" class isn''t a reference type - its a value type, so in:

public stringtemp(ref String inp)
{
k = inp ;
}

even though you are ref''fing inp, the ''k=inp'' is still done as a value
assignment.

In order to do what you want, you''ll have to put the ''string inp'' as a
member of another class, and pass the class instance instead of the string
itself.

--
-mdb


public stringtemp(ref String inp)

says that you can change "inp" _in the constructor_ and the
corresponding argument variable will change on the outside.

String k;

says what? Does it say "k is a reference to a string"? No, it says, "k
is a string". So, when you say

this.k = inp;

what you''re saying is, "k should be the same string as is contained in
inp*". Since you never avail yourself of the opportunity to change inp
_within the constructor_, you just change k, but never inp,
"stringtochange" is never changed.

Just because you declare a parameter as "ref" does not mean that its
"refness" is sticky and follows that string value wherever it goes.
Now, if C# were allow you to say something like:

public class stringtemp
{
ref String k;

public stringtemp(ref String inp)
{
this.k = inp;
}
...
}

then we might have something going here. However "ref String k" is not
a valid field declaration, so you''re out of luck.

By the time you get to the Change method, the fact that "inp" was
originally declared "ref" is completely irrelevant. It''s only relevant
within the constructor.

One of the design goals of C# and .NET was to avoid the kind of pointer
mayhem that can occur in C and C++. That''s why you can''t declare
variables that hold references: they would just be pointers under
another name, and open the door to all kinds of madness. Take another
look at your example, and think of it like this:

String stringtochange = "Hello";
stringtemp t = new stringtemp(ref stringtochange) ;
... 200 lines of complex code here ...
t.Change() ;

suddenly, without any warning or any indication in the code that it
might happen, the variable "stringtochange" *magically* changes after
the call to t.Change(). How easy is it to maintain that code? This is
exactly what C# seeks to avoid.
* Technically, this is a bit of a lie. k is, in fact, a reference to a
string, since strings are held by reference in string variables.
However, "inp" is a reference to a reference to a string, which is what
you need in order to change the argument passed in on the call.
Correctly, I should have said that there is no way in C# to declare k
as a private member that is a reference to a reference to a string,
which is what you would need in order to create the behaviour you want
to see. However, I rephrased it all in order to avoid confusion. In
this case you can think of strings as values, even though they''re
really references. For the purposes of this explanation the distinction
is irrelevant.


Not so. Strings are indeed a reference type. After all, System.String is a
class, not a struct. However, because strings are immutable, they have very
value-like semantics, because any change to a string results in a completely
new string being created "under the hood". In most situations this makes a
string "behave" superficially as if it were a value type. For example:

myString = "foo" + someOtherString;

.... really results in the compiler emitting code that works more like this:

myString = new String("foo" + someOtherString)

.... which will not change the original myString reference if it exists in
the caller''s context, which makes this *appear* to behave like a value type.
But, all that is passed into a conventional string parameter of a method is
a *reference* to a string, nonetheless.

--Bob

----- Original Message -----
From: "mdb" <m_b_r_a_y@c_t_i_u_s_a__d0t__com>
Newsgroups: microsoft.public.dotnet.languages.csharp
Sent: Wednesday, June 01, 2005 4:09 PM
Subject: Re: ''ref'' question

The "string" class isn''t a reference type - its a value type, so in:



这篇关于'ref'问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆