C#字符串从结构中消失

C#字符串从结构中消失,c#,.net,winforms,string,dictionary,C#,.net,Winforms,String,Dictionary,好的。。我有一个非常棘手的问题,我认为这与C#如何处理值类型和引用类型有关,但我不确定到底是什么错误 public partial class LogicSimulationViewerForm : Form { private Dictionary<string, PointStruct> pointValues; private void SearchPoint(string code) { ReadDefaultPointValue

好的。。我有一个非常棘手的问题,我认为这与C#如何处理值类型和引用类型有关,但我不确定到底是什么错误

public partial class LogicSimulationViewerForm : Form
    {

    private Dictionary<string, PointStruct> pointValues;


private void SearchPoint(string code)
    {
        ReadDefaultPointValuesResponse result = ddcdao.ReadDefaultPoint(points);
        pointValues = new Dictionary<string, PointStruct>();

        for (int j = 0; j < result.pointidentifier.Length; j++)
        {
            if (!pointValues.ContainsKey(result.pointidentifier[j]))
            {
                PointStruct ps = new PointStruct();
                ps.name = "Random String"; 
                ps.pointidentifier = result.pointidentifier[j];
                ps.outofservice = result.outofservice[j];

                pointValues.Add(result.pointidentifier[j], ps);
                ...
ps.pointidentifier和ps.outofservice显示正确,但无论我做什么,ps.name始终返回为null。如何解决此问题

编辑:根据要求,我将添加更多代码以进一步说明问题:

public struct PointStruct
{
    public string pointidentifier;
    public string affect;
    public string outofservice;
    public string priorityarray;
    public string pointtype;
    public string alarmstate;
    public string correctvalue;
    public string presentvalue;
    public string name;
    public string test;
}

只要没有巫毒(显式字段布局、属性间接寻址等),就绝对没有理由让字段自己擦除,不管它是
还是
结构

如果它是一个
,我们可能会将其归因于其他地方的不小心更新,即

var foo = pointValues[key];
// snip 2000 lines
foo.name = newValue; // which happens to be null
这当然会更新与字典引用的基本对象相同的基本对象。但是不适用于
结构,因为副本是分开的(除非直接在数组中更新)

考虑到您声明
pointValues.Add(…)
仅在一个位置使用,我所能看到的唯一原因是您正在通过索引器在其他位置覆盖它:

pointValues[key] = newValueWithANullName;

尽管如此,这一切都是如此;除非您有一些非常具体的原因,
PointStruct
成为
struct
几乎没有什么意义。在我看来,它应该是一个
。对于
struct
,它非常“胖”。而且在大多数情况下,
struct
s应该是不可变的。

只要没有伏都教(显式字段布局、属性间接寻址等),就绝对没有理由让字段自己擦除,不管它是
类还是
结构

如果它是一个
,我们可能会将其归因于其他地方的不小心更新,即

var foo = pointValues[key];
// snip 2000 lines
foo.name = newValue; // which happens to be null
这当然会更新与字典引用的基本对象相同的基本对象。但是不适用于
结构,因为副本是分开的(除非直接在数组中更新)

考虑到您声明
pointValues.Add(…)
仅在一个位置使用,我所能看到的唯一原因是您正在通过索引器在其他位置覆盖它:

pointValues[key] = newValueWithANullName;

尽管如此,这一切都是如此;除非您有一些非常具体的原因,
PointStruct
成为
struct
几乎没有什么意义。在我看来,它应该是一个
。对于
struct
,它非常“胖”。而且在大多数情况下,
struct
s应该是不可变的。

存储在
字典
中的struct的任何
字符串
字段都会更改为除了存储在
字典
中时所保存的值之外的任何值。您的名字实际上是一个文本
“随机字符串”
,还是您使用该文本来表示其他函数?您是否已确认所讨论的功能实际上正在工作

与这里的一些人不同,我非常喜欢可变结构,尽管.net对它们的支持有局限性,因为它们允许结构的所有者控制谁可以对其进行变异。相比之下,如果对可变类对象的引用曾经暴露于外部代码中,则不知道何时或由谁修改它。
PointStruct
是一个结构,这意味着从
字典
检索的结构的字段内容有99.44%的几率与存储结构时的字段内容相同。添加一个检查,确保
名称
字段在存储到
字典
时不为空,您几乎肯定会发现问题。这比使用可变类要好得多,因为在可变类中,您必须检查外部代码以确保没有任何东西改变它

附录

可变结构有一个缺点,即如果您有任何结构成员(构造函数或属性设置器除外)对
this
进行了变异,则尝试在只读上下文中使用此类成员将生成伪代码,但不会生成任何编译器诊断。正确支持值类型语义的语言和框架要求对变异的
this
成员进行标记,并禁止在只读上下文中使用此类成员,但遗憾的是.net没有此类标记。它只是猜测构造函数和属性设置器将改变底层结构,而getter和其他方法则不会。如果`名称'字段用struct方法填充,例如

void ComputeName(void) { Name = someRandomString(); } void ComputeName(void) { Name=someRandomString(); } 我强烈建议您将其替换为静态方法:

void ComputeName(ref theStruct) { theStruct.Name = someRandomString(); } 无效计算名称(参考结构) { theStruct.Name=someRandomString(); }
如果前一个函数是在
PointStruct
的只读实例上调用的,那么编译器将——如前所述——编译时不会有任何抱怨,但生成的代码将无法工作。但是,试图将
PointStruct
的只读实例传递给后者,将导致编译器错误。

存储在<代码>字典
中的结构的任何<代码>字符串
字段都会更改为保存除存储在<代码>字典
中时所保存的值以外的任何值,这将非常令人惊讶。您的名字实际上是一个文本
“随机字符串”
,还是您使用该文本来表示其他函数?您是否已确认所讨论的功能实际上正在工作

与这里的一些人不同,我非常喜欢可变结构,尽管.net对它们的支持有局限性,因为它们允许结构的所有者控制谁可以对其进行变异。相比之下,如果对可变类对象的引用曾经暴露于外部代码中,则不知道它何时或由谁提供