Following up on a previous question, here is my general class structure..
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 toItem<SubItemTwo>in terms of assignment compatibility thanstringis toDateTime.If you must do it this way, then you’ll have to use reflection. This should do the trick: