C# 在C中更新列表中结构的属性#
我有一个C# 在C中更新列表中结构的属性#,c#,struct,C#,Struct,我有一个列表,其中Cat是一个struct,它有一个Id和一个名称 如何更改id为7的猫的名称 我做了(不假思索) 当然,结构是值类型。那么,是否可以使用这样的技术,或者我必须将.Single更改为for循环,并存储索引以用更新的结构替换它?因为structs是值类型,并且由于值类型被复制,myCat最终得到列表中cat的副本。您需要对结构本身进行操作,而不是对其副本进行操作 此外,只有当structs的字段是单个变量或数组的一部分时,才可以直接修改这些字段列表的索引器返回一个副本,因此C#编译
列表
,其中Cat
是一个struct
,它有一个Id和一个名称
如何更改id为7的猫的名称
我做了(不假思索)
当然,结构是值类型。那么,是否可以使用这样的技术,或者我必须将
.Single
更改为for
循环,并存储索引以用更新的结构替换它?因为struct
s是值类型,并且由于值类型被复制,myCat
最终得到列表中cat的副本。您需要对结构本身进行操作,而不是对其副本进行操作
此外,只有当struct
s的字段是单个变量或数组的一部分时,才可以直接修改这些字段<代码>列表的索引器返回一个副本,因此C#编译器产生“无法修改值类型”错误
我知道的唯一解决方案(除了制作Cat
aclass
or)是制作catList
数组:
var indexOf = catArray
.Select((Cat, Index) => new {Cat, Index})
.Single(p => p.Cat.Id == 7).Index;
catArray[indexOf].Name = "Dr Fluffykins";
要更新列表中ID为7的项的值,必须首先找到其在列表中的位置。一旦知道其索引,可以使用适用于所有暴露现场结构的正常方法进行更新:
int index = myList.Find( it => it.ID == 7);
if (index >= 0)
{
var temp = myList[index];
temp.Name = "Dr Fluffykins";
myList[index] = temp;
}
注意,有些人认为结构不如类,因为没有最后一行,上面的代码永远不会工作。我想说的是相反的:在许多情况下,它们是优越的,因为仅仅知道某个东西是一个暴露的字段结构就足以知道最后一行是必要的和足够的。相反,如果所讨论的类型是一个可变类,那么无论最后一行是否存在,代码都可能按预期工作,或者可能产生意外的副作用
顺便说一句,如果你经常使用Id
,我建议你使用字典而不是列表。或者,您可以使用Cat[]
和字典来跟踪阵列中不同Cat的位置。后一种方法的一个优点是,使用Cat[]
,与列表不同,可以简单地说:
myArray[index].Name = "Dr Fluffykins";
直接更新数组中的项。这种方法非常有效。或者,您可以编写一个类似于列表的类,该类包括一个方法“ActionItem(int-index,ref-T-it)
和ActionItem(int-index,ref-T-it,ref-TParam1-param1)
方法,可以调用该方法myList.ActionItem(index,(ref-Cat-it)=>it.Name=“Dr Fluffykins”)
或--iftheNewName
是一个变量,myList.ActOnItem(index,(ref Cat it,ref string theNewName)=>it.Name=theNewName)
注意,可以将newname
存储到项中,而无需将其作为ref
或非ref参数传递,但是关闭局部变量的lambda要比不关闭局部变量的lambda慢得多。可能更值得创建Cat
aclass
。我倾向于找到创建struct
类型的标准我不知道更多关于猫的知识,我下意识的反应是“为什么是结构?”?把它变成一门课。“在我的示例中,我将其存储在mvc网站的全局缓存中,因此我希望使占用空间尽可能小,因此使用struct。此外,我现在对结构很感兴趣,想让它们工作:)内存占用可能会小一些,但由于结构的值类型语义,访问成本可能会超过这一点。我只能想象struct
和class
之间的占用在您的场景中可以忽略不计。Moreso:如果对同一个Cat
有两个或多个引用,作为struct
它将复制其所有字段,而不仅仅是复制指向Cat
实例的引用指针。我可以想象,在这种实践中,使用结构将消耗更多内存。(但数量仍然微不足道)这似乎是一个常见的陷阱。下面是一个很好的答案。有道理,我想知道LINQ是否不可能(对于更新操作)。在C#?@SLC中没有存储对结构的引用的奇特方法我不知道有什么方法可以在方法调用的上下文之外使用对struct
s的引用。但是,有一种相对简单的方法可以让LINQ为您查找索引,避免循环(请参阅更新)。如果Cat
是一个struct
,如何从catList[indexOf]
修改它?这难道不是隐式地从索引器方法返回副本吗?(我甚至不认为这将编译)事实上,他是正确的,我只是尝试了它,你不能修改它。我认为删除答案的人是正确的,你需要一套方法。@SLC:类似的问题。返回的Cat
是一个副本。您可以调用“SetName”方法,但它仍在更改副本。catList
中的原始Cat
仍未修改。
myArray[index].Name = "Dr Fluffykins";