如何在不更改其类型的情况下订购 IGrouping?
How to order IGrouping without changing its type?
我有一个 IGrouping 类型的对象,想在不更改对象类型的情况下对组内的元素进行排序。
也就是说,我有
var tmp = group.OrderBy(x => x);
group
属于 IGrouping<int, someanonymousclass>
类型,我希望 tmp
也属于 IGrouping<int, someanonymousclass>
类型。
一种解决方法是将其更改为字典或新的匿名 class,但我希望 tmp 的具体类型为 IGrouping<int, someanonymousclass>
.
换句话说:我想对 IGrouping<int, someanonymousclass>
对象的元素进行排序。如果我使用 OrderBy
,它会将 group
的类型更改为 IOrderedEnumerable
,我无法再访问 group.Key
。我怎样才能维持 group
的类型?
示例:
var states = SimulationPanel.innerPanel.Children.OfType<StateBar>().Where(x => x.isSensorState())
.GroupBy(x => (SensorElement)x.BauplanElement,
x => new
{
Start = (decimal)(x.Margin.Left / SimulationPanel.Zoom),
Width = (decimal)(x.Width / SimulationPanel.Zoom),
State = x.State
});
var group = states.First();
var tmp = group.OrderBy(x => x.Start);
var key = tmp.Key; //This does not work, because tmp is not of type IGrouping
我知道我可以在分组前使用 OrderBy
。不过我不想那样做。
如果你可以,就把顺序放在前面,例如
var states = SimulationPanel.innerPanel
.Children
.OfType<StateBar>()
.Where(x => x.isSensorState())
.OrderBy(x => (decimal)(x.Margin.Left / SimulationPanel.Zoom))
.GroupBy(...);
(或在 OrderBy
前加一个 Select
并使 GroupBy
更简单。)
如果您真的需要这个,您可以编写自己的 IGrouping<TKey, TElement>
实现和扩展方法来对元素进行排序并将它们保留在列表中:
public static class GroupExtensions
{
public IGrouping<TKey, TElement, TOrderKey> OrderBy
(this IGrouping<TKey, TElement> grouping,
Func<TElement, TOrderKey> orderKeySelector)
{
return new GroupingImpl<TKey, TElement>
(grouping.Key, grouping.OrderBy(orderKeySelector));
}
private class GroupingImpl<TKey, TElement> : IGrouping<TKey, TElement>
{
private readonly TKey key;
private readonly List<TElement> elements;
internal GroupingImpl(TKey key, IEnumerable<TElement> elements)
{
this.key = key;
this.elements = elements.ToList();
}
public TKey Key { get { return key; } }
public IEnumerator<TElement> GetEnumerator()
{
return elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
我有一个 IGrouping 类型的对象,想在不更改对象类型的情况下对组内的元素进行排序。
也就是说,我有
var tmp = group.OrderBy(x => x);
group
属于 IGrouping<int, someanonymousclass>
类型,我希望 tmp
也属于 IGrouping<int, someanonymousclass>
类型。
一种解决方法是将其更改为字典或新的匿名 class,但我希望 tmp 的具体类型为 IGrouping<int, someanonymousclass>
.
换句话说:我想对 IGrouping<int, someanonymousclass>
对象的元素进行排序。如果我使用 OrderBy
,它会将 group
的类型更改为 IOrderedEnumerable
,我无法再访问 group.Key
。我怎样才能维持 group
的类型?
示例:
var states = SimulationPanel.innerPanel.Children.OfType<StateBar>().Where(x => x.isSensorState())
.GroupBy(x => (SensorElement)x.BauplanElement,
x => new
{
Start = (decimal)(x.Margin.Left / SimulationPanel.Zoom),
Width = (decimal)(x.Width / SimulationPanel.Zoom),
State = x.State
});
var group = states.First();
var tmp = group.OrderBy(x => x.Start);
var key = tmp.Key; //This does not work, because tmp is not of type IGrouping
我知道我可以在分组前使用 OrderBy
。不过我不想那样做。
如果你可以,就把顺序放在前面,例如
var states = SimulationPanel.innerPanel
.Children
.OfType<StateBar>()
.Where(x => x.isSensorState())
.OrderBy(x => (decimal)(x.Margin.Left / SimulationPanel.Zoom))
.GroupBy(...);
(或在 OrderBy
前加一个 Select
并使 GroupBy
更简单。)
如果您真的需要这个,您可以编写自己的 IGrouping<TKey, TElement>
实现和扩展方法来对元素进行排序并将它们保留在列表中:
public static class GroupExtensions
{
public IGrouping<TKey, TElement, TOrderKey> OrderBy
(this IGrouping<TKey, TElement> grouping,
Func<TElement, TOrderKey> orderKeySelector)
{
return new GroupingImpl<TKey, TElement>
(grouping.Key, grouping.OrderBy(orderKeySelector));
}
private class GroupingImpl<TKey, TElement> : IGrouping<TKey, TElement>
{
private readonly TKey key;
private readonly List<TElement> elements;
internal GroupingImpl(TKey key, IEnumerable<TElement> elements)
{
this.key = key;
this.elements = elements.ToList();
}
public TKey Key { get { return key; } }
public IEnumerator<TElement> GetEnumerator()
{
return elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}