.NET / C#:是否可以将内存中的一个对象替换为另一个?

时间:2011-08-25 18:27:28

标签: c# .net object reference replace

以此代码为例:

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()

6 个答案:

答案 0 :(得分:4)

变化:

//Jooky = new Jooky { Name = "Bob" };
Jooky.Name = "Bob" ;

.Single()的resullt是实例(对象)的引用。你只是用一个覆盖了一个新对象的引用。旧对象未被更改或覆盖。

要了解正在发生的事情,并调整您的目标,请查找“值类型和参考类型”。有很多阅读要做。


阅读评论后:

如果您的详细信息(Jookies)将独立于其所有者(Flookies)进行更改,那么您只需要另一层间接。

一个简单的建议:

  • 不存储对细节的引用(因为它们会改变)
  • 存储DetailId(JookyId1,JookyId2)
  • 将详细信息保存在字典中(Dictionary<int,Jooky>
  • 在Owner中创建一个(readonly)属性,通过在字典中查找来获取Detail1。

答案 1 :(得分:4)

也许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只能CruiseWithAuthority BuickCentury {{1}}就可以了(特别是当司机是6'2" )

即使在允许无限内存访问的C / C ++中,我仍会对执行您想要执行的操作的代码感到非常惊讶。这就是为什么大多数其他答案都提出了不同的方法或设计。

答案 2 :(得分:3)

您可以在C#中编写不安全的代码,使您可以在直接内存上运行。

详情请看这里:

Pointers and arrays in C#

您会注意到您可以使用C和C ++中熟悉的指针(*)和地址(&amp;)。

以下是一个不安全交换的示例,我认为这是您所追求的: Unsafe swap in C#

答案 3 :(得分:0)

Jooky = new Jooky { Name = "Bob" }; 
Flookies[0].Jooky1=Jooky;

如果要在不分配引用的情况下替换另一个对象,只需将所有数据字段复制到另一个对象即可。不确定我是否正确理解了你的问题。

答案 4 :(得分:0)

当您使用引用时,对引用的每个赋值都会更改引用所指向的对象。

所以,当你说:

Jooky Jooky = Jookies.Single(j => j.Id == 2);

您正在使用Id == 2向Jookie创建参考。然后,当你说Jooky = new Jooky { Name = "Bob" };时,你告诉你创建的引用指向你刚刚创建的Jooky。

因此,如果要为Jookie1对象的Flookies[0]属性(对于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

答案 5 :(得分:0)

如果您有权访问Jookie课程,则可以添加一个包含Flookie的父Jookie的属性:

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; }
}

然后访问父Flookie并更改它的Jookie1属性:

Flookie flookie = Jookies.Single(j => j.Id == 2).Parent;
flookie.Jookie1 = new Jookie { Name = "Bob" }