C# 实例复制/传递对象引用与 Java 不同?

发布于 11-17 10:35 字数 1405 浏览 3 评论 0原文

class Player
{
   private Location location;

   public Location getLocation()
   {
        return location;
   }

    public void setLocation(Location location)
    {
        this.location = location;
    }
}

...

class Location
{
    int x,y,z;

    public Location(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Location(Location location)
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }


    public void updateLocation(Location location) //the fix..
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }
}

说..你这样做

Player p1 = new Player();
Player p2 = new Player();
p1.setLocation(p2.getLocation());

现在,当您尝试修改其他人的位置时,就会出现错误/问题。两个玩家的位置变化完全相同,因为他们现在共享相同的位置。

当然,下面这个也能正常工作。

p1.setLocation(new Location(p2.getLocation()));

但问题是它总是创建一个新对象..当我可以更新现有实例时..?如何在默认情况下更新现有实例而不像下面那样使用我自己的方法来解决此问题。

我必须使用下面的方法来解决这个问题(默认情况下任何方法都可以做到这一点,而不需要像下面这样做)

    public void setLocation(Location location)
    {
        if (this.location == null)
            this.location= new Location(location);
        else
            this.location.updateLocation(location);
    }

有人知道我可能不知道的技巧吗?谢谢。

class Player
{
   private Location location;

   public Location getLocation()
   {
        return location;
   }

    public void setLocation(Location location)
    {
        this.location = location;
    }
}

...

class Location
{
    int x,y,z;

    public Location(int x, int y, int z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Location(Location location)
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }


    public void updateLocation(Location location) //the fix..
    {
        this.x = location.x;
        this.y = location.y;
        this.z = location.z;
    }
}

Say.. you do

Player p1 = new Player();
Player p2 = new Player();
p1.setLocation(p2.getLocation());

Now the bug/problem occurs when you attempt to modify other persons location. Both players locations changes exactly the same, as they both now share the same location.

So of course this below will work just fine.

p1.setLocation(new Location(p2.getLocation()));

but the problem is it always creates a new object.. when I could just update the existing instance..? how do I update the existing instance on default without making my own methods like I did below to fix this.

I had to fix this using the method below (any way to do this by default without doing like this below)

    public void setLocation(Location location)
    {
        if (this.location == null)
            this.location= new Location(location);
        else
            this.location.updateLocation(location);
    }

Anyone knows any tricks I may not know about? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爺獨霸怡葒院2024-11-24 10:35:15

类是引用类型。当您调用此方法时:

p1.setLocation(p2.getLocation());

您不是将实例数据传递给方法,而是传递对实例的引用。引用就像指向存储实例数据的堆(内存)的托管指针。这非常重要,因为否则对实例数据的所有更改都将仅具有方法范围。当您调用此方法时:

this.location = location;

您正在分配引用而不是数据。这意味着 locationthis.location 将指向内存中的同一个块。

这是 C# 编程的要点。如果您希望复制而不是引用数据,则必须使用结构而不是类。

无论如何,将值从一个实例重新分配到另一个实例是相当常见的任务。

编辑:

您指出由于开销您不想创建新对象。

  • 过早的优化是万恶之源
  • 在有意义的地方以及你发现它确实会导致性能下降的地方进行优化。 这里您有一些关于简单笔记本电脑上的对象实例化的值。

另外说您不喜欢属性很奇怪 - 您正在使用 C# 进行编程,因此请正确使用它,否则您的同事不会喜欢您。

Classes are reference types. When you call this:

p1.setLocation(p2.getLocation());

you are not passing instance data to the method but the reference to the instance. Reference is like managed pointer to heap (memory) where the instance's data are stored. That is quite important because otherwise all changes to instance's data would have only method scope. When you call this:

this.location = location;

you are assigning the reference not the data. It means that both location and this.location will point to the same block in the memory.

That is the essential point in C# programming. If you want data to be copied instead of referenced you must use structures instead of classes.

Anyway reassiging values from one instance to another instance is quite common task.

Edit:

You pointed that you don't want to create new object because of overhead.

  • Premature optimization is source of evil
  • Optimize where it make sense and where you see that it really make performance drop. Here you have some values about object instantiation on simple laptops.

Also saying that you don't like properties is strange - you are programming in C# so use it correctly otherwise your colleagues will not like you.

愁以何悠2024-11-24 10:35:15

在 .NET 中传递引用本质上与 Java 相同。然而.NET 我们还有一些额外的功能。

例如,out 和 ref 参数可用于返回作为参数传递的值。例如

    public void SaveProductFeature(ref SaveCollection save)
    {
       SaveCollection.Product.ProductId = Product.Save(SaveCollection.Product);
    }

Passing references around in .NET is essentially the same as Java. However.NET we have a few extra features.

For example the out and the ref params can be used to return values passed as arguments. e.g.

    public void SaveProductFeature(ref SaveCollection save)
    {
       SaveCollection.Product.ProductId = Product.Save(SaveCollection.Product);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文