.NET/C#:是否可以用另一个对象替换内存中的一个对象
本文关键字:一个对象 替换 内存 是否 NET | 更新日期: 2023-09-27 18:06:35
以以下代码为例:
class Jooky
{
static long Last;
public Jooky() { Id += Last++; }
public long Id { get; set; }
public string Name { get; set; }
}
class Flooky
{
public Flooky() { Jooky1 = new Jooky(); Jooky2 = new Jooky(); }
public Jooky Jooky1 { get; set; }
public Jooky Jooky2 { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Flooky> Flookies = new List<Flooky>();
//I build a collection of flookies to emulate the service call of
//FlookyProxy.GetAllFlookies().
for (int i = 0; i < 5; i++) Flookies.Add(new Flooky());
//This makes a collection of all the jookies in all the flookies.
var Jookies = Flookies.Select(f => f.Jooky1).Union(Flookies.Select(f => f.Jooky2));
//I get the jooky.
Jooky Jooky = Jookies.Single(j => j.Id == 2);
//Fig 1: I just got a jooky out of the collection. One of the flookies
//has a reference to this jooky. I want to set the jooky to a new
//reference, but still want the same flooky to reference it.
Jooky = new Jooky { Name = "Bob" };
//I get the jooky again
Jooky = Jookies.Single(j => j.Id == 2);
//However, this writes an empty string because only the Jooky variable
//I previously declared was affected.
Console.WriteLine(Jookies.Single(j => j.Id == 2).Name);
//Basically, I want the code in Fig 1 above to be the same as:
//Flooy.Jooky = new Jooky { Name = "Bob" };
Console.Read();
}
}
基本上,变量A引用内存中的Aa,变量B引用内存中对象Bb。我想让A引用内存中与B相同的对象,而不是像A = B;
那样。相反,我想用另一个替换内存中的物理对象,最终就像Aa = Bb;
一样。
这有可能吗?
更新:主要规则:我不能直接引用flooky,所以我不能完全像Flooky.Jooky1 = new Jooky()
或Flookies[3].Jooky1 = new Jooky()
。
也许这在havardhu建议的不安全代码中是可能的,但在安全代码中绝对不可能。重要的是要理解为什么做你想做的事情是不安全的。它不仅破坏了封装,还破坏了类型安全性。考虑这个例子。
class Me : IHaveCar
{
BuickCentury myCentury = new BuickCentury(2004);
public Car Car { get { return myCentury; } }
public void Drive()
{
myCentury.CruiseWithAuthority();
}
}
class EvilOilChangeService
{
public void ChangeOil(IHaveCar customer)
{
Car car = customer.Car;
// here's the fictional "replace object in memory" operator
car <<== new VolkswagenBeetle(2003);
}
}
EvilOilChangeService
可以创建myCentury
引用VolkswagenBeetle
!当我尝试使用Drive
时,我会遇到麻烦,因为VolkswagenBeetle
不能像BuickCentury
那样使用CruiseWithAuthority
(尤其是当驾驶员身高6英尺2英寸时(
即使在允许随意访问内存的C/C++中,我仍然会对代码做你想做的事情感到非常惊讶。这就是为什么大多数其他答案都建议使用不同的方法或设计。
更改:
//Jooky = new Jooky { Name = "Bob" };
Jooky.Name = "Bob" ;
.Single()
的结果是对实例(对象(的引用。您只是用一个对新对象的引用来覆盖引用。旧对象未被更改或覆盖。
要了解发生了什么,并调整您的目标,请查找"值类型和引用类型"。有很多阅读要做。
阅读评论后:
如果你的细节(Jookies(将独立于他们的所有者(Flookies(而改变,那么你只需要另一层间接性。
一个简单的建议:
- 不要存储对详细信息的引用(因为它们会更改(
- 而是存储DetailId(JookyId1,JookyId2(
- 将详细信息保存在词典中(
Dictionary<int,Jooky>
( - 在Owner中创建一个(只读(属性,通过在字典中查找它来获得Detail1
您可以用C#编写不安全的代码,这使您能够在直接内存上操作。
查看此处了解详细信息:
C#中的指针和数组
您会注意到,您可以使用C和C++中熟悉的指针(*(和地址(&(。
下面是一个不安全交换的例子,我认为这就是你想要的:C#中的不安全交换
Jooky = new Jooky { Name = "Bob" };
Flookies[0].Jooky1=Jooky;
如果您想用另一个对象替换一个对象,而不只是指定引用,则只需将所有数据字段复制到另一对象即可。不确定我是否正确理解了你的问题。
使用引用时,对引用的每次赋值都会更改引用指向的对象。
所以,当你说:
Jooky Jooky = Jookies.Single(j => j.Id == 2);
您正在使用Id == 2
创建对Jookie的引用。然后,当你说Jooky = new Jooky { Name = "Bob" };
时,你是在告诉你创建的引用指向你刚刚创建的Jooky。
因此,如果你想为Flookies[0]
对象的Jookie1
属性(wich是引用Jookie对象的占位符(设置一个新值,你必须说:
Flookies[0].Jooky1 = new Jooky { Name = "Bob" };
(如@Ashley John的回答所述(。
这样,您就告诉Flookies[0].Jooky1
引用指向new Jooky { Name = "Bob" };
对象。
有关详细说明,请参阅http://msdn.microsoft.com/en-us/library/ms173104.aspx。
如果您有权访问Jookie
类,您可以添加一个包含Jookie
:的父Flookie
的属性
class Jooky
{
static long Last;
public Jooky(Flooky parent)
{
Id += Last++;
Parent = parent;
}
public long Id { get; set; }
public string Name { get; set; }
public Flooky Parent { get; private set; }
}
然后访问父CCD_ 25并更改其CCD_ 26属性:
Flookie flookie = Jookies.Single(j => j.Id == 2).Parent;
flookie.Jookie1 = new Jookie { Name = "Bob" }