为什么以下代码无效?
如果我将h
从属性更改为字段,则可以正常工作!
或者,如果我将FileHeader
从struct
更改为class
则可行!
我只是在寻找它为什么不起作用的答案。
public class MyFile
{
public struct FileHeader
{
public List<string> ColNames
{
get;
set;
}
public void setColNames()
{
ColNames = new List<string>();
ColNames.Add("address");
}
}
public FileHeader h
{
get;
set;
}
}
public class Program
{
static void Main(string[] args)
{
MyFile o = new MyFile();
o.h.setColNames();
Console.WriteLine(o.h.ColNames[0]); // <- Doesn't work! No elements
string line = System.Console.ReadLine();
}
}
答案 0 :(得分:9)
这一行:
o.h.setColNames();
相当于:
FileHeader tmp = o.h;
tmp.setColNames();
由于FileHeader
是结构,因此tmp
的值是o
中字段值的副本。修改tmp
不会更改o.h
。
我建议:
h
的属性和setColNames
的方法都违反此答案 1 :(得分:1)
属性实际上是从您身上抽象出来的方法。它最终成为一个方法调用Set ..和一个名为Get ...的方法,它检索隐藏的后备变量或设置隐藏的后备变量。
结构是值类型。将值类型传递给方法时,它会复制它们。例如。 o.h.setColNames正在添加到副本,而不是o.h的支持字段的实际实例。
如果您制作了像
这样的房产public int SomeInteger {get;组; }
它也是一个值类型,但它起作用,因为setter正在设置实际的实例,而getter会返回匹配的副本。
但是使用你的代码,你用一个类包装你的struct,所以你总是得到一个没有调用setColNames的副本。
这是我在这里发布的一些脏代码,但它演示了如何保持这个设计并通过让结构引用它的父类来设置新副本。
public class MyFile
{
public struct FileHeader
{
internal MyFile _parent;
public List<string> ColNames
{
get;
set;
}
public void setColNames()
{
ColNames = new List<string>();
ColNames.Add("address");
_parent._h = this;
}
}
private FileHeader _h = new FileHeader();
public FileHeader h
{
get { return _h; }
}
public MyFile()
{
_h._parent = this;
}
}
class Program
{
static void Main(string[] args)
{
MyFile o = new MyFile();
o.h.setColNames();
Console.WriteLine(o.h.ColNames[0]);
string line = System.Console.ReadLine();
}
}