C# 为什么可以';t通过不带'的方法分配纹理2d;出';?

C# 为什么可以';t通过不带'的方法分配纹理2d;出';?,c#,xna,C#,Xna,我有一个类包含一个纹理2D,如下所示: public class TextureData { public Texture2D texture; } 当我加载所有纹理时,我会通过以下方法进行处理: public void LoadAllTextures() { foreach(string s in texturesToBeLoaded) { TextureData data = new TextureData(); LoadTextur

我有一个类包含一个纹理2D,如下所示:

public class TextureData
{
    public Texture2D texture;
}
当我加载所有纹理时,我会通过以下方法进行处理:

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

它很好用


编辑:好吧,我现在的理解是

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.
}
public void LoadAllTextures()
{
foreach(texturesToBeLoaded中的字符串s)
{
TextureData=新的TextureData();
//这里,data.texture的内存地址==0x0001
LoadTexture(s,data.texture/*0x0001*/);
}
}
public void LoadTexture(字符串文件名,Texture2D texture/*现在是0x0001*/)
{
纹理=content.Load(文件名);
//现在,参数设置为0x0002,而不是data.texture本身。
}

C#按值传递变量-传递引用的副本,但原始变量或字段保持不变。添加
out
(或
ref
)使其按引用传递,从而更新原始变量/字段。

C#按值传递变量-传递引用的副本,但原始变量或字段保持不变。添加
out
(或
ref
)使其通过引用传递,从而更新原始变量/字段。

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;
}
public void LoadAllTextures()
{
foreach(texturesToBeLoaded中的字符串s)
{
纹理数据=加载纹理;
//在这里处理数据
}
}
public Texture2D LoadTexture(字符串文件名)
{
Texture2D texture=content.Load(文件名);
返回纹理;
}

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;
}
public void LoadAllTextures()
{
foreach(texturesToBeLoaded中的字符串s)
{
纹理数据=加载纹理;
//在这里处理数据
}
}
public Texture2D LoadTexture(字符串文件名)
{
Texture2D texture=content.Load(文件名);
返回纹理;
}

这是因为您正在修改引用的副本。先前的
data.texture
指向内存位置,假设调用
LoadTexture(s,data.texture)时
048
参数纹理现在保存值
048
。在方法
LoadTexture
的第一行中,您正在为它分配一个新的内存位置,因此现在
texture
指向一个全新的位置,但不是
048
。这就是为什么你看不到任何变化

但是,如果更新
纹理的任何属性
,也会看到原始数据中的更改

考虑以下情况:

public class TempClass
{
    public string MyProperty { get; set; }
}
Main
方法中,您可以执行以下操作:

TempClass tc = new TempClass();
tc.MyProperty = "Some value";
SomeMethod(tc);
其中,您的方法是:

public static void SomeMethod(TempClass temp)
{
    temp = null;
}
现在,它不会将
TempClass
的对象
tc
设置为null


您应该看到Jon Skeet的这篇文章:

,这是因为您正在修改引用的副本。先前的
data.texture
指向内存位置,假设调用
LoadTexture(s,data.texture)时
048
参数纹理现在保存值
048
。在方法
LoadTexture
的第一行中,您正在为它分配一个新的内存位置,因此现在
texture
指向一个全新的位置,但不是
048
。这就是为什么你看不到任何变化

但是,如果更新
纹理的任何属性
,也会看到原始数据中的更改

考虑以下情况:

public class TempClass
{
    public string MyProperty { get; set; }
}
Main
方法中,您可以执行以下操作:

TempClass tc = new TempClass();
tc.MyProperty = "Some value";
SomeMethod(tc);
其中,您的方法是:

public static void SomeMethod(TempClass temp)
{
    temp = null;
}
现在,它不会将
TempClass
的对象
tc
设置为null


您应该看到Jon Skeet的这篇文章:

这种混淆可能来自于通过引用传递的含义。在C#中,对象通过引用传递。这意味着,如果修改函数中对象的属性,这些更改将反映在调用函数中,并且它们都引用了同一对象。但是,通过引用传递并不意味着如果更新变量以引用函数中的不同对象(例如,通过创建新对象),则调用函数中的变量将更新为引用相同对象。如果这是您想要的行为,则必须使用ref或out。

这种混淆可能来自于通过引用传递的含义。在C#中,对象通过引用传递。这意味着,如果修改函数中对象的属性,这些更改将反映在调用函数中,并且它们都引用了同一对象。但是,通过引用传递并不意味着如果更新变量以引用函数中的不同对象(例如,通过创建新对象),则调用函数中的变量将更新为引用相同对象。如果这是您想要的行为,则必须使用ref或out。

Texture2D是一个类。我的理解是,传递类(而不是结构)就是通过引用传递;没错。但是,这里您试图更改保存引用的变量,而不是实例。好的。你能检查一下我原始帖子中的编辑并评论我是否理解正确吗?@Inlinevoid,是的,我想你明白了。:)太棒了,谢谢你的帮助(来自其他人,也来自四面八方!)。不过,Texture2D是一门课。我的理解是,传递类(而不是结构)就是通过引用传递;没错。但是,这里您试图更改保存引用的变量,而不是实例。好的。你能检查一下我原来的帖子中的编辑吗