c#修改列表中的结构<T> [英] c# modifying structs in a List<T>

查看:21
本文介绍了c#修改列表中的结构<T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

小问题:如何修改List 中的单个项目?(或者更准确地说,存储在 List 中的 struct 的成员?)

Short question: How can I modify individual items in a List? (or more precisely, members of a struct stored in a List?)

完整说明:

首先,下面使用的struct定义:

First, the struct definitions used below:

public struct itemInfo
{
    ...(Strings, Chars, boring)...
    public String nameStr;
    ...(you get the idea, nothing fancy)...
    public String subNum;   //BTW this is the element I'm trying to sort on
}

public struct slotInfo
{
    public Char catID;
    public String sortName;
    public Bitmap mainIcon;
    public IList<itemInfo> subItems;
}

public struct catInfo
{
    public Char catID;
    public String catDesc;
    public IList<slotInfo> items;
    public int numItems;
}

catInfo[] gAllCats = new catInfo[31];

gAllCats 在加载时填充,并在程序运行时填充.

gAllCats is populated on load, and so on down the line as the program runs.

当我想对 subItems 数组中的 itemInfo 对象进行排序时,就会出现问题.我正在使用 LINQ 来执行此操作(因为似乎没有任何其他合理的方法可以对非内置类型的列表进行排序).所以这就是我所拥有的:

The issue arises when I want to sort the itemInfo objects in the subItems array. I'm using LINQ to do this (because there doesn't seem to be any other reasonable way to sort lists of a non-builtin type). So here's what I have:

foreach (slotInfo sInf in gAllCats[c].items)
{
    var sortedSubItems =
        from itemInfo iInf in sInf.subItems
        orderby iInf.subNum ascending
        select iInf;
    IList<itemInfo> sortedSubTemp = new List<itemInfo();
    foreach (itemInfo iInf in sortedSubItems)
    {
        sortedSubTemp.Add(iInf);
    }
    sInf.subItems.Clear();
    sInf.subItems = sortedSubTemp;   // ERROR: see below
}

错误是无法修改 'sInf' 的成员,因为它是一个 'foreach 迭代变量'".

The error is, "Cannot modify members of 'sInf' because it is a 'foreach iteration variable'".

a,这个限制没有意义;这不是 foreach 结构的主要用途吗?

a, this restriction makes no sense; isn't that a primary use of the foreach construct?

b,(也是出于恶意)如果不修改列表,Clear() 会做什么?(顺便说一句,如果我删除最后一行并运行它,根据调试器,列表确实会被清除.)

b, (also out of spite) what does Clear() do if not modify the list? (BTW, the List does get cleared, according to the debugger, if I remove the last line and run it.)

所以我尝试采用不同的方法,看看它是否可以使用常规的 for 循环.(显然,这只是允许的,因为 gAllCats[c].items 实际上是一个 IList;我认为它不允许您索引常规的 List 这样.)

So I tried to take a different approach, and see if it worked using a regular for loop. (Apparently, this is only allowable because gAllCats[c].items is actually an IList; I don't think it will allow you to index a regular List this way.)

for (int s = 0; s < gAllCats[c].items.Count; s++)
{
    var sortedSubItems =
        from itemInfo iInf in gAllCats[c].items[s].subItems
        orderby iInf.subNum ascending
        select iInf;
    IList<itemInfo> sortedSubTemp = new List<itemInfo>();
    foreach (itemInfo iInf in sortedSubItems)
    {
        sortedSubTemp.Add(iInf);
    }
    //NOTE: the following two lines were incorrect in the original post
    gAllCats[c].items[s].subItems.Clear();
    gAllCats[c].items[s].subItems = sortedSubTemp;   // ERROR: see below
}

这次的错误是无法修改'System.Collections.Generic.IList.this[int]'的返回值,因为它不是变量."啊!如果不是变量,它是什么?什么时候变成返回值"了?

This time, the error is, "Cannot modify the return value of 'System.Collections.Generic.IList.this[int]' because it is not a variable." Ugh! What is it, if not a variable? and when did it become a 'return value'?

我知道必须有一种正确"的方法来做到这一点;我是从 C 背景来的,我知道我可以用 C 来做(尽管需要一些手动内存管理.)

I know there has to be a 'correct' way to do this; I'm coming to this from a C background and I know I could do it in C (albeit with a good bit of manual memory management.)

我四处搜索,似乎 ArrayList 已经过时了,转而支持泛型类型(我使用的是 3.0)并且我不能使用数组,因为大小需要动态.

I searched around, and it seems that ArrayList has gone out of fashion in favor of generic types (I'm using 3.0) and I can't use an array since the size needs to be dynamic.

推荐答案

查看 for 循环方法,在 编译错误文档:

Looking at the for-loop approach, the reason (and solution) for this is given in the documentation for the compilation error:

试图修改一个值作为结果产生的类型一个中间表达式,但不是存储在一个变量中.这个错误可以当您尝试直接修改泛型中的结构收藏.

An attempt was made to modify a value type that is produced as the result of an intermediate expression but is not stored in a variable. This error can occur when you attempt to directly modify a struct in a generic collection.

要修改struct,先赋值到局部变量,修改变量,然后分配变量返回集合中的项目.

To modify the struct, first assign it to a local variable, modify the variable, then assign the variable back to the item in the collection.

因此,在您的 for 循环中,更改以下几行:

So, in your for-loop, change the following lines:

catSlots[s].subItems.Clear();
catSlots[s].subItems = sortedSubTemp;   // ERROR: see below

...进入:

slotInfo tempSlot = gAllCats[0].items[s];
tempSlot.subItems  = sortedSubTemp;
gAllCats[0].items[s] = tempSlot;

我删除了对 Clear 方法的调用,因为我认为它没有添加任何内容.

I removed the call to the Clear method, since I don't think it adds anything.

这篇关于c#修改列表中的结构&lt;T&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆