跨越继承阵列添加元素结合在一起,LINQ [英] Adding elements together across inherited arrays, LINQ
问题描述
这是前一个问题的后续行动,这是我的一般类结构。
的 http://stackoverflow.com/questions/3711224/combine-elements-in-a-list-based - 酮型和 - summate-其值-LINQ
我试图使用他们各自的。新增方法的物品结合,但由于。实体框架的考虑,我只能处理基本类型(不是接口)
使用System.Linq的;
使用System.Collections.Generic;
接口项< T>
{
不要再增加(T项目);
}
抽象类项目
{
公共ItemType的类型;
公共int值;
}
类SubItemOne:项目,项目<&SubItemOne GT;
{
公众诠释附加{搞定;组; }
公共SubItemOne添加(SubItemOne项目)
{
// ..
}
}
类SubItemTwo:项目,项目< SubItemTwo>
{
公众诠释MOREDATA {搞定;组; }
公众诠释OtherData {搞定;组; }
公共SubItemTwo添加(SubItemTwo项目)
{
// ...
}
}
类SubItemThree :项目,项目<&SubItemThree GT;
{
公众诠释StillOtherData {搞定;组; }
公众诠释SecondaryData {搞定;组; }
公众诠释TertiaryData {搞定;组; }
公共SubItemThree添加(SubItemThree项目)
{
// ...
}
}
类的ItemType
{
公共字符串名称;
}
类测试
{
公共静态无效的主要()
{
名单,LT;&的ItemType GT;类型=新的List<&的ItemType GT;();
types.Add(新的ItemType {名称=类型1});
types.Add(新的ItemType {名称=2型});
types.Add(新的ItemType {名称=3类});
名单,LT;项目>项目=新的List<项目>();
的for(int i = 0;我小于10;我++)
{
items.Add(新SubItemOne
{
类型=类型。单(T => t.Name ==类型1),
附加= I
});
}
的for(int i = 0;我小于10;我++)
{
items.Add(新SubItemTwo
{
键入= types.Single(T => t.Name ==2型),
MOREDATA = 10,
OtherData = I + 10
});
}
的for(int i = 0;我小于10;我++)
{
items.Add(新SubItemThree
{
键入= types.Single(T => t.Name ==类型3),
SecondaryData = 1000,
StillOtherData = 1874
TertiaryData = I * 10
});
}
名单,LT;项目>结合=新名单<项目>();
//创建具有3个项目中,每个类型中的一个列表,与该类型的合计值的总和。
//包含类型不总是在运行时已知的。
//我试图调用。新增方法上的项目,以便他们可以collatted在一起。然而
//他们都回报的基本类型。
}
}
的问题是,你将不得不在更高层次来处理接口,因此将不能够这样做一般(即使用泛型类型参数)。你将必须定义一个非通用接口(即使它除了当前的通用接口),这些类为了做你以后实施。 项目< SubItemOne>
没有更多的涉及到项目< SubItemTwo>
比分配兼容性方面字符串
是的DateTime
。
如果你必须这样做,那么你将不得不使用反射。这应该做的伎俩:
词典< ItemType的,项目>总和=新词典< ItemType的,项目>();
的foreach(在项目VAR项目)
{
项目currSum;
如果(sum.TryGetValue(项目。形式,走出currSum))
{
总和[项目。形式] =(项目)item.GetType()。GetInterfaces() 。单(
I => i.Name ==项目)。实现getMethod(添加)
.Invoke(currSum,新的对象[] {项目});
}
,否则
{
sum.Add(项目。形式,项目);
}
}
名单,LT;项目>合并= sum.Values.ToList();
Following up on a previous question, here is my general class structure..
I am trying to combine the items using their respective .Add methods, but because of Entity Framework considerations, I can only deal with base types (Not interfaces).
using System.Linq;
using System.Collections.Generic;
interface Item<T>
{
T Add(T item);
}
abstract class Item
{
public ItemType Type;
public int Value;
}
class SubItemOne : Item, Item<SubItemOne>
{
public int Additional { get; set; }
public SubItemOne Add(SubItemOne item)
{
// ..
}
}
class SubItemTwo : Item, Item<SubItemTwo>
{
public int MoreData { get; set; }
public int OtherData { get; set; }
public SubItemTwo Add(SubItemTwo item)
{
// ...
}
}
class SubItemThree : Item, Item<SubItemThree>
{
public int StillOtherData { get; set; }
public int SecondaryData { get; set; }
public int TertiaryData { get; set; }
public SubItemThree Add(SubItemThree item)
{
// ...
}
}
class ItemType
{
public string Name;
}
class Test
{
public static void Main()
{
List<ItemType> types = new List<ItemType>();
types.Add(new ItemType { Name = "Type1" });
types.Add(new ItemType { Name = "Type2" });
types.Add(new ItemType { Name = "Type3" });
List<Item> items = new List<Item>();
for (int i = 0; i < 10; i++)
{
items.Add(new SubItemOne
{
Type = types.Single(t => t.Name == "Type1"),
Additional = i
});
}
for (int i = 0; i < 10; i++)
{
items.Add(new SubItemTwo
{
Type = types.Single(t => t.Name == "Type2"),
MoreData = 10,
OtherData = i + 10
});
}
for (int i = 0; i < 10; i++)
{
items.Add(new SubItemThree
{
Type = types.Single(t => t.Name == "Type3"),
SecondaryData = 1000,
StillOtherData = 1874,
TertiaryData = i * 10
});
}
List<Item> combined = new List<Item>();
// create a list with 3 items, one of each 'type', with the sum of the total values of that type.
// types included are not always known at runtime.
// I am trying to invoke the .Add Method on the items so that they can be collatted together. However
// they all return as the base type.
}
}
The problem is that you're going to have to deal with the interfaces at a higher level, and thus won't be able to do so generically (i.e., using the generic type arguments). You're going to have to define a non-generic interface (even if it's in addition to your current generic interface) that these classes implement in order to do what you're after. Item<SubItemOne>
is no more related to Item<SubItemTwo>
in terms of assignment compatibility than string
is to DateTime
.
If you must do it this way, then you'll have to use reflection. This should do the trick:
Dictionary<ItemType, Item> sum = new Dictionary<ItemType, Item>();
foreach (var item in items)
{
Item currSum;
if (sum.TryGetValue(item.Type, out currSum))
{
sum[item.Type] = (Item)item.GetType().GetInterfaces().Single(
i => i.Name == "Item").GetMethod("Add")
.Invoke(currSum, new object[] { item });
}
else
{
sum.Add(item.Type, item);
}
}
List<Item> combined = sum.Values.ToList();
这篇关于跨越继承阵列添加元素结合在一起,LINQ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!