我有一个类似于持有Texture2D的类:
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 LoadTexture(string filename, Texture2D texture)
要
public void LoadTexture(string filename, out Texture2D texture)
工作正常。
编辑:好吧,所以我现在理解它的方式是......
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.
}
答案 0 :(得分:3)
C#按值传递变量 - 传递了引用的副本,但原始变量或字段保持不变。添加out
(或ref
)会使其通过引用传递,然后更新原始变量/字段。
答案 1 :(得分:1)
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;
}
答案 2 :(得分:1)
那是因为您正在修改引用的副本。早期data.texture
指向内存位置,假设048
,当您调用LoadTexture(s, data.texture);
时,参数纹理现在保持值048
。在方法LoadTexture
的第一行中,您为其分配了一个新的内存位置,因此现在texture
指向全新的内容,而不是048
。这就是为什么你没有看到任何变化。
但是,如果您更新texture
的任何属性,您也会看到原始数据的更改。
考虑以下情况:
public class TempClass
{
public string MyProperty { get; set; }
}
使用Main
方法,您可以:
TempClass tc = new TempClass();
tc.MyProperty = "Some value";
SomeMethod(tc);
你的SomeMethod在哪里:
public static void SomeMethod(TempClass temp)
{
temp = null;
}
现在不会将tc
的对象TempClass
设置为null。
你应该看到Jon Skeet的这篇文章:Parameter passing in C#
答案 3 :(得分:1)
混淆可能来自于通过引用传递的含义。在C#中,对象通过引用传递。这意味着如果修改函数中对象的属性,那些更改将反映在调用函数中,并且它们都具有对同一对象的引用。但是,传递引用并不意味着如果更新变量以引用函数中的另一个对象(例如,通过创建新对象),则将更新调用函数中的变量以引用同一对象。如果这是您想要的行为,则必须使用ref或out。