更改从linq查询收到的项属性

时间:2014-12-23 11:20:47

标签: c# linq properties

我需要更改查询返回的列表项的值...它必须简单,但我无法使用linq看到它。

该列表由此结构的元素组成:

public struct HeaderButton
    {
        public string content {get; set;}
        public BitmapImage icon {get; set;}
        public PageContainerFactory.ContainerType containerType {get; set;}
        public bool IsSelected { get; set; }
    }

private List<HeaderButton> _headerButtons;
public List<HeaderButton> HeaderButtons
    {
        get
        {
            if (_headerButtons == null)
                _headerButtons = new List<HeaderButton>();
            return _headerButtons;
        }
        set { _headerButtons = value; }
    }

我试过了:

HeaderButtons.First(x => x.containerType == CurrentContainer.CType).IsSelected = true;

编译器告诉我:

无法修改'System.Linq.Enumerable.First(System.Collections.Generic.IEnumerable,System.Func)'的返回值,因为它不是变量

现在我正在尝试查询:

var h = HeaderButtons.First(x => x.containerType == CurrentContainer.CType);
h.IsSelected = true;

由于编译错误,我不得不在var中获取元素。并且如上面的代码所示,显然“h”并不指向“HeaderButtons”真实元素,因为它是一个新的HeaderButton对象而不是引用。

2 个答案:

答案 0 :(得分:1)

根据你的意见,我决定用一个嵌套类来代替结构,因为这种对象不是在内容类之外使用的,现在这是一个类(对象引用)而不是结构(值)一切正常。

代码:

sealed class MainViewModel : ViewModelNavigator
{

    internal class HeaderButton
    {
        public string Content { get; set; }
        public BitmapImage Icon { get; set; }
        public PageContainerFactory.ContainerType ContainerType { get; set; }
        public bool IsSelected { get; set; }
    }

...

private List<HeaderButton> _headerButtons;
public List<HeaderButton> HeaderButtons
    {
        get
        {
            if (_headerButtons == null)
                _headerButtons = new List<HeaderButton>();
            return _headerButtons;
        }
        set { _headerButtons = value; }
    }

...

HeaderButtons.First(x => x.ContainerType == CurrentContainer.CType).IsSelected = true;

答案 1 :(得分:0)

编译器可以帮助您避免在脚下拍摄。

因为HeaderButton是一个结构,所以它是通过值而不是通过引用传递的。这意味着Linq First运算符正在(并将返回)列表中元素的值副本。

因为First的返回值没有分配给任何东西,所以它是临时的,并且会在语句的末尾超出范围,而且因为它是值副本而不是对列表中项目的引用您对其所做的更改不会影响列表中的项目。

如果这是编译,你可能很容易被误导,认为你已经更新了列表中的项目,这是你没有的。通过拒绝编译编译器可以避免必须追踪可能是一个棘手的bug来查找。

如果您有理由将HeaderButton保留为结构,那么这样的语句将使您能够更新它。

var hb = HeaderButtons.First(x => x.containerType == CurrentContainer.CType);
HeaderButtons[HeaderButtons.IndexOf(hb)].IsSelected = true;

如果你走这条路,你需要确保你的struct的相等操作以对你有用的方式运行,这取决于与'如果你有理由将HeaderButton保持为结构'相同的因素,因为部分想要使用结构而不是类意味着需要值相等而不是引用相等语义。