【发布时间】:2015-04-10 15:07:10
【问题描述】:
我看到的行为与我对 List.First() 的预期不同:
我构建了一些包含列表的测试应用程序
public abstract class GridTemplateModelBase : INotifyPropertyChanged, IDisposable
{
Public ObservableCollection<ColumnModel> Columns
{
get
{
return _columns;
}
protected set
{
_columns = value;
OnPropertyChanged();
}
}
}
ColumnModel 类包含一个名为 GroupIndex 的属性。我想从Columns 列表中选择特定项目并通过另一个类设置GroupIndex 属性,所以我使用了以下代码:
//choose the list item I want to change
var test = GridProfile.Columns.First(p => p.FieldName == item);
//Change GroupIndex value
test.GroupIndex = 1;
我希望这段代码能够更改列表项的GroupIndex 值,但似乎`Columns.First()' 方法返回了此列表项的副本。
请看以下图片:
所选列表项的初始 GroupIndex 为 -1
在 GroupIndex 值改变后测试上面代码中的参数值,你可以看到它变成了 1
运行上述代码后所选列表项的值 => 仍然是 -1
如果List.First() 方法返回所选列表项的引用,我们必须看到该列表项的值与上面代码中的test 参数相同,但令人惊讶的是,情况并非如此。
有人能解释一下Linq.First() 方法的工作原理吗?
希望我的问题很清楚
这是ColumnModel类的内容:
public class ColumnModel : INotifyPropertyChanged
{
/// <summary>
/// Initializes a new instance of the ColumnModel class.
/// </summary>
public ColumnModel()
{
AllowEdit = DefaultBoolean.True;
SortIndex = -1;
GroupIndex = -1;
}
private string _cellToolTip;
private int _sortIndex;
private ColumnSortOrder _sortOrdering;
private bool _isReadOnly;
private int _groupIndex;
private bool _isVisible;
private bool _fixedWidth;
private double _minWidth;
private double _width;
private EditSettingsHorizontalAlignment _cellContentAlighnment;
private ColumnProfile _profileTemplate;
private string _fieldHeader;
private string _fieldName;
private DefaultBoolean allowEdit;
// Specifies the name of a data source field to which the column is bound.
public string FieldName
{
get
{
return _fieldName;
}
set
{
_fieldName = value;
OnPropertyChanged();
}
}
public string FieldHeader
{
get
{
return _fieldHeader;
}
set
{
_fieldHeader = value;
OnPropertyChanged();
}
}
// Specifies the type of template to load
public ColumnProfile ProfileTemplate
{
get
{
return _profileTemplate;
}
set
{
_profileTemplate = value;
OnPropertyChanged();
}
}
public EditSettingsHorizontalAlignment CellContentAlighnment
{
get
{
return _cellContentAlighnment;
}
set
{
_cellContentAlighnment = value;
OnPropertyChanged();
}
}
public double Width
{
get
{
return _width;
}
set
{
_width = value;
OnPropertyChanged();
}
}
public double MinWidth
{
get
{
return _minWidth;
}
set
{
_minWidth = value;
OnPropertyChanged();
}
}
public bool FixedWidth
{
get
{
return _fixedWidth;
}
set
{
_fixedWidth = value;
OnPropertyChanged();
}
}
public bool IsVisible
{
get
{
return _isVisible;
}
set
{
_isVisible = value;
OnPropertyChanged();
}
}
public int GroupIndex
{
get
{
return _groupIndex;
}
set
{
_groupIndex = value;
OnPropertyChanged();
}
}
public bool IsReadOnly
{
get
{
return _isReadOnly;
}
set
{
_isReadOnly = value;
OnPropertyChanged();
}
}
public ColumnSortOrder SortOrdering
{
get
{
return _sortOrdering;
}
set
{
_sortOrdering = value;
OnPropertyChanged();
}
}
public DefaultBoolean AllowEdit
{
get { return allowEdit; }
set
{
allowEdit = value;
OnPropertyChanged();
}
}
public string CellToolTip
{
get
{
return _cellToolTip;
}
set
{
_cellToolTip = value;
OnPropertyChanged();
}
}
public int SortIndex
{
get
{
return _sortIndex;
}
set
{
_sortIndex = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
更新:
通过您的 cmets,我了解到 List.First() 返回引用类型,可能我的代码包含问题或者我的调试器可能返回错误结果 - 将检查它。
这里是First 源代码(来源:@Enigmativity):
public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
throw Error.ArgumentNull("source");
if (predicate == null)
throw Error.ArgumentNull("predicate");
foreach (TSource source1 in source)
{
if (predicate(source1))
return source1;
}
throw Error.NoMatch();
}
谢谢
【问题讨论】:
-
我怀疑这会复制你的对象 - 我宁愿认为你的
GroupIndex设置器可能有问题(它真的设置了_groupIndex)吗? -
@CarstenKönig - 是的,二传手很好,我仔细检查了这个
-
发布
ColumnModel课程。真的可以是struct吗? -
@JonEgerton 正如我所提到的,它是一个引用类型 - 请参阅我的帖子 - 添加了
ColumnModel类 -
什么是选定列表项?正如我在您的图片中看到的,您的代码将
test.GroupIndex更改为1。您比较过FieldName属性吗?也许在您的收藏中,您有多个具有相同FieldName的项目?也许您的 选定列表项 根本不在GridProfile.Columns中。您的问题现在无法为其他任何人解决。First()不会创建副本,因此您的问题不在您发布的代码范围内。