对象引用 - 停电了 [英] Object References - got a blackout

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

问题描述

大家好,


我的脑子里有一个关于参考的小洞。这就是

我想要做的事情:我正在调用一个函数,传递一个

业务对象的引用进行编辑。该函数克隆对象,调用

编辑器对话框让用户编辑对象,然后 - 取决于

DialogResult - 分配克隆/备份副本或修改后的

对象本身作为参考。也许我在指针中想得太多

引用 - 但是不可能改变引用(不是

引用的对象),如下所示:


public static bool EditMyObject(ref MyObject o)

{

MyObject o2 = o.Clone();

if(...){

o = ...

} else {//返回备份副本

o = o2; < br $>
}

}


在这种情况下,结果将始终是原始的o实例,永远不会是

o2。


请解开我脑中的结;-) - 提前谢谢你,


Phil

Hi all,

I''ve got a little hole in my head concerning references. Here''s what
I''m trying to do: I''m calling a function, passing the reference of a
business object for editing. The function clones the object, calls an
editor dialog to let the user edit the object, and then - depending on
the DialogResult - assigns either the clone/backup copy or the modified
object itself to the reference. Maybe I''m thinking too much in pointer
references - but isn''t it possible to alter a reference (not the
referenced object) like this:

public static bool EditMyObject(ref MyObject o)
{
MyObject o2 = o.Clone();
if (...) {
o = ...
} else { // return backup copy
o = o2;
}
}

In this case, the result would always be the original o instance, never
o2.

Please, untie the knot in my brain ;-) - thank you in advance,

Phil

推荐答案

" Philipp Reif" < ph ********** @ gmail.com写信息

新闻:11 ******************** **@h54g2000cwb.googlegr oups.com ...
"Philipp Reif" <ph**********@gmail.comwrote in message
news:11**********************@h54g2000cwb.googlegr oups.com...

[...]

在这种情况下,结果将永远是最初的o实例,永远不会是b $ b o2。
[...]
In this case, the result would always be the original o instance, never
o2.



将永远是?为什么这么说?


在我看来,你想要的和你发布的代码是一样的。你确实可以通过引用一个函数传递一个引用变量,并修改引用的
。在您的示例中,如果将局部参数变量o

设置为某个新引用,则调用者用作参数的变量将更改为引用同样的参考。


什么不能按你的预期工作?


Pete

"Would always be"? Why do you say that?

It seems to me that what you want and the code you posted are the same. You
can indeed pass a reference variable by reference to a function, and modify
the reference. In your example, if you set the local parameter variable "o"
to some new reference, the variable used as the parameter by the caller will
be changed to refer to that same reference.

What is not working as you expect it to?

Pete


感谢您的帮助,Pete。
Thanks for your assistance, Pete.

在我看来,您想要的和您发布的代码是一样的。你确实可以通过引用一个函数传递一个引用变量,并修改引用的

It seems to me that what you want and the code you posted are the same. You
can indeed pass a reference variable by reference to a function, and modify
the reference.



嗯,确切地说这不起作用。我正在将一个ref传递给实例A到这个函数的函数,在函数内部修改ref以指向A的一个

克隆,但是当函数返回时,原始实例仍在使用
。这就是为什么我问 - 我现在已经编码16年了,

我真的怀疑我的能力,因为我遇到了这个。


我可以在这里发布完整的原始代码,如果这样会有所帮助。


Phil

Well, exactly that is not working. I''m passing a ref to instance A to
the function, the ref is modified inside the function to point to a
clone of A, but as the function returns, the original instance is still
being used. That''s why I asked - I''ve been coding now for 16 years,
and I really doubted my abilities as I came across this.

I could post the complete original code here, if that would help.

Phil


嗨Philipp,
Hi Philipp,

在这种情况下,结果将始终是原始的o实例,永远不会是
o2。
In this case, the result would always be the original o instance, never
o2.



不跟你100%这个,但看起来你想要的是什么
do是传入一个对象然后让用户修改对象,他们可以返回
然后退出更改或提交更改。在C#中,参数是按值传递的
,即使基础类型可以通过引用传递

ie


给定一个人class,这是一个引用类型,因为它不是从System.ValueType继承




class Person

{

私人字符串名称;


public Person(字符串名称)

{

this.name = name ;

}


公共字符串名称

{

get

{

返回this.name;

}

}

}


如果我们创建一个人的实例,并使用ref关键字将其传递给没有

的函数,则通过引用传递person实例(即内部

参数的函数引用对象的相同实例

传递给函数但是我们无法更改函数外部的引用

指向的函数参数本身当函数被调用时被复制了




类人物

{

私人字符串名称;


public Person(字符串名称)

{

this.name = name;

}


公共字符串名称

{

get

{

返回this.name;

}

set

{

this.name = value;

}

}

}


班级计划

{

static void Main(string [] args)

{

Person p1 = new Person(" frank");

ChangePersonName1(p1);

//现在p1.Name ==" bob"


ChangePersonName2(p1);

//仍然是p1.Name ==" bob"


ChangePersonName3(ref p1);

//这里p1.Name ==" john" ;

Console.ReadLine();

}


static void ChangePersonName1(Person person)

{

person.Name = bob;

}


静态无效ChangePersonName2(个人)

{

// person参数是

// frank变量的副本,所以如果我们改变了

// person变量指向的那个我们不是

//更改frank变量指向的内容。

person = new Person(mark);


// here here.Name ==" mark"但仍然是p1.name ==" bob"

}


static void ChangePersonName3(ref person person)

{

//这里的person变量和p1变量是相同的

//变量所以改变一个人所指的将改变

//什么是p1指的是。


person = new Person(" john");


// here person.Name ==" john"和p1.Name ==" john"

}


我个人不喜欢使用ref关键字,因为它可以制作代码

令人困惑且不容易理解。而不是你拥有的代码:


public static bool EditMyObject(ref MyObject o)

{

MyObject o2 = o。克隆();

if(...){

o = ...

} else {//返回备份副本
o = o2;

}

}

我会做类似的事情:

public static MyObject EditMyObject(MyObject o)

{

MyObject o2 = o.Clone();


//让用户修改o2实例。

showGUI(o2);


if(userWantsToAcceptChanges)

{

返回o2 ;

}

其他

{//返回备份副本

返回o;

}

}


你不需要一个bool表示成功与否(如果出现问题

你可以抛出异常),然后调用代码就像:

MyObject myObj = new MyObject();

myObj = EditMyObject(myObj) ;


也是一个重要的po int要记住的是,如果你克隆一个像

这样的对象你的例子,如果你暴露任何一个对象的属性,你需要做一个深层复制由o2实例引用,否则

用户可以修改这些引用,然后单击取消,此时你将返回o实例,该实例将保持不变但是项目参考
它的b $ b仍然可以被修改。对于值类型,即从System.ValueType派生

的类型传递给方法时的对象是浅层复制

与引用类型不同,有关详细信息,请参阅:
http://www.yoda.arachsys.com/csharp/parameters .html


就个人而言,当我创建GUI时,我通常使用Command设计模式

,它提供了允许撤消/重做的额外好处通过单元测试帮助提高GUI代码的可测试性。


HTH

Mark。

-
http://www.markdawson.org

" Philipp Reif"写道:

Not following you 100% on this one, but it looks like what you are trying to
do is pass in an object and then let the user modify the object, they can
then back out of the changes or commit the changes. In C# parameters are
passed by value, even though the underlying type could be passed by reference
i.e.

Given a Person class, this is a reference type since it is not inheriting
from System.ValueType:

class Person
{
private string name;

public Person(string name)
{
this.name = name;
}

public string Name
{
get
{
return this.name;
}
}
}

If we create an instance of a person, and pass it to a function without
using the ref keyword the person instance is passed by reference (i.e. inside
the function the parameter is refering to the same instance of the object
that was passed into the function) but we cannot change what the reference
outside the function is pointing to since the parameter itself was copied
when the function was called:

class Person
{
private string name;

public Person(string name)
{
this.name = name;
}

public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
}

class Program
{
static void Main(string[] args)
{
Person p1 = new Person("frank");
ChangePersonName1(p1);
//Now p1.Name == "bob"

ChangePersonName2(p1);
//Still p1.Name == "bob"

ChangePersonName3(ref p1);
//Here p1.Name == "john"
Console.ReadLine();
}

static void ChangePersonName1(Person person)
{
person.Name = "bob";
}

static void ChangePersonName2(Person person)
{
//the person parameter is a copy of the
//frank variable so if we change what the
//person variable points to we are not
//changing what the frank variable points to.
person = new Person("mark");

//here person.Name == "mark" but still p1.name == "bob"
}

static void ChangePersonName3(ref Person person)
{
//here the person variable and p1 variable are the same
//variable so changing what person refers to will change
//what p1 refers to.

person = new Person("john");

//here person.Name == "john" and p1.Name == "john"
}

I personally do not like to use the ref keyword since it can make code
confusing and not easy to follow. Instead of the code you have:

public static bool EditMyObject(ref MyObject o)
{
MyObject o2 = o.Clone();
if (...) {
o = ...
} else { // return backup copy
o = o2;
}
}
I would do something like:
public static MyObject EditMyObject(MyObject o)
{
MyObject o2 = o.Clone();

//let user modify o2 instance.
showGUI(o2);

if (userWantsToAcceptChanges)
{
return o2;
}
else
{ // return backup copy
return o;
}
}

You don''t need a bool to indicate success or not (if something goes wrong
you can throw an exception), then the calling code would be something like:

MyObject myObj = new MyObject();
myObj = EditMyObject(myObj);

Also an inportant point to remember is that if you cloning an object like in
your example, you will need to make a deep copy if you are exposing any of
the properties of a object being referenced by the o2 instance, otherwise a
user could modify these references and then click cancel at which point you
would return the o instance which would be unchanged but the items references
by it could still have been modified. For value types, i.e. types deriving
from System.ValueType the object when passed to a method is shallow copied
unlike reference types, for more info, see:
http://www.yoda.arachsys.com/csharp/parameters.html

Personally when I create a GUI I normally use the Command design pattern
which gives the added benefit of allowing undo/redo and helps increase the
testability of your GUI code through unit tests.

HTH
Mark.
--
http://www.markdawson.org
"Philipp Reif" wrote:


大家好,


我的脑子里有一个关于参考的小洞。这就是

我想要做的事情:我正在调用一个函数,传递一个

业务对象的引用进行编辑。该函数克隆对象,调用

编辑器对话框让用户编辑对象,然后 - 取决于

DialogResult - 分配克隆/备份副本或修改后的

对象本身作为参考。也许我在指针中想得太多

引用 - 但是不可能改变引用(不是

引用的对象),如下所示:


public static bool EditMyObject(ref MyObject o)

{

MyObject o2 = o.Clone();

if(...){

o = ...

} else {//返回备份副本

o = o2; < br $>
}

}


在这种情况下,结果将始终是原始的o实例,永远不会是

o2。


请解开我脑中的结;-) - 提前谢谢你,


Phil

Hi all,

I''ve got a little hole in my head concerning references. Here''s what
I''m trying to do: I''m calling a function, passing the reference of a
business object for editing. The function clones the object, calls an
editor dialog to let the user edit the object, and then - depending on
the DialogResult - assigns either the clone/backup copy or the modified
object itself to the reference. Maybe I''m thinking too much in pointer
references - but isn''t it possible to alter a reference (not the
referenced object) like this:

public static bool EditMyObject(ref MyObject o)
{
MyObject o2 = o.Clone();
if (...) {
o = ...
} else { // return backup copy
o = o2;
}
}

In this case, the result would always be the original o instance, never
o2.

Please, untie the knot in my brain ;-) - thank you in advance,

Phil


这篇关于对象引用 - 停电了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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