简体   繁体   English

为什么不能通过没有'out'的方法来分配Texture2D?

[英]Why can't a Texture2D be assigned through a method without 'out'?

I've got a class that holds a Texture2D like so: 我有一个像这样保存Texture2D的类:

public class TextureData
{
    public Texture2D texture;
}

When I load all of my textures, I handle it through methods like this: 加载所有纹理时,我通过以下方法进行处理:

public void LoadAllTextures()
{
    foreach(string s in texturesToBeLoaded)
    {
        TextureData data = new TextureData();
        LoadTexture(s, data.texture);
        // data.texture is still null.
    }
}
public void LoadTexture(string filename, Texture2D texture)
{
    texture = content.Load<Texture2D>(filename);
    // texture now holds the texture information but it doesn't
    // actually retain it when the method ends...why?
}

Am I missing something here? 我在这里想念什么吗? If I change 如果我改变

public void LoadTexture(string filename, Texture2D texture)

To

public void LoadTexture(string filename, out Texture2D texture)

It works fine. 工作正常。


EDIT: Alright so the way I understand it now is this... 编辑:好的,所以我现在了解的是这个...

public void LoadAllTextures()
{
    foreach(string s in texturesToBeLoaded)
    {
        TextureData data = new TextureData();
        // here, data.texture's memory address == 0x0001
        LoadTexture(s, data.texture /*0x0001*/);
    }
}
public void LoadTexture(string filename, Texture2D texture /* this is now 0x0001 */)
{
    texture = content.Load<Texture2D>(filename);
    // now the PARAMETER is set to 0x0002, not data.texture itself.
}

C# passes variables by value - a copy of the reference is passed but the original variable or field remains untouched. C#按值传递变量-传递引用的副本,但原始变量或字段保持不变。 Adding out (or ref ) makes it pass by reference, which then causes the original variable/field to be updated. 加入out (或ref )使得它通过引用,其然后导致原始变量/字段进行更新通过。

Lucero's answer is correct - the practical change you would make is to change your methods to work as follows: Lucero的答案是正确的-您将进行的实际更改是将方法更改为如下所示:

public void LoadAllTextures()
{
    foreach(string s in texturesToBeLoaded)
    {
        TextureData data = LoadTexture(s);
        // do something with data here
    }
}

public Texture2D LoadTexture(string filename)
{
    Texture2D texture = content.Load<Texture2D>(filename);
    return texture;
}

That is because you are modifying the copy of the reference. 那是因为您正在修改参考的副本。 Earlier data.texture points to a memory location suppose 048 , when you call LoadTexture(s, data.texture); 调用LoadTexture(s, data.texture);时,较早的data.texture指向一个内存位置,假设为048 LoadTexture(s, data.texture); the parameter texture now holds the value 048 . 现在,参数texture的值为048 In the first line in your method LoadTexture you are assigning it a new memory location, so now texture points to something totally new, but not 048 . 在方法LoadTexture的第一行中,您将为其分配一个新的内存位置,因此texture现在指向的是全新的东西,而不是048 That is why you don`t see any change. 这就是为什么您看不到任何变化的原因。

But if you update any property of texture , you will see the change in original data as well. 但是,如果更新texture任何属性,您也会看到原始数据中的更改。

Consider the following case: 考虑以下情况:

public class TempClass
{
    public string MyProperty { get; set; }
}

In your Main method you can do: 在您的Main方法中,您可以执行以下操作:

TempClass tc = new TempClass();
tc.MyProperty = "Some value";
SomeMethod(tc);

Where as your SomeMethod is: 您的SomeMethod在哪里:

public static void SomeMethod(TempClass temp)
{
    temp = null;
}

Now that will not set the object tc of TempClass to null. 现在,不会将TempClass的对象tc设置为null。

You should see this article by Jon Skeet: Parameter passing in C# 您应该看到Jon Skeet的这篇文章: 在C#中传递参数

The confusion probably comes from what it means to pass by reference. 混淆可能来自通过引用传递的含义。 In C#, objects are passed by reference. 在C#中,对象通过引用传递。 This means if you modify properties of the object in a function, those changes will be reflected in the calling function as well as they both have references to the same object. 这意味着,如果您在函数中修改对象的属性,则这些更改将反映在调用函数中,并且它们都引用同一对象。 However, pass-by-reference does NOT mean that if you update the variable to refer to a different object (eg by creating a new object) in the function that the variable in the calling function will be updated to refer to the same object. 但是,按引用传递并不意味着如果您在函数中更新变量以引用不同的对象(例如,通过创建新对象),则调用函数中的变量将被更新为引用相同的对象。 You must use ref or out if this is the behavior you want. 如果这是您想要的行为,则必须使用ref或out。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM