跨越继承阵列添加元素结合在一起,LINQ [英] Adding elements together across inherited arrays, LINQ

查看:110
本文介绍了跨越继承阵列添加元素结合在一起,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个项目中,每个类型中的一个列表,与该类型的合计值的总和。
//包含类型不总是在运行时已知的。

//我试图调用。新增方法上的项目,以便他们可以collat​​ted在一起。然而
//他们都回报的基本类型。
}
}


解决方案

的问题是,你将不得不在更高层次来处理接口,因此将不能够这样做一般(即使用泛型类型参数)。你将必须定义一个非通用接口(即使它除了当前的通用接口),这些类为了做你以后实施。 项目< 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..

http://stackoverflow.com/questions/3711224/combine-elements-in-a-list-based-on-type-and-summate-their-values-linq

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屋!

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