C#字符串从结构中消失
好的。。我有一个非常棘手的问题,我认为这与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
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对它们的支持有局限性,因为它们允许结构的所有者控制谁可以对其进行变异。相比之下,如果对可变类对象的引用曾经暴露于外部代码中,则不知道它何时或由谁提供