I have a problem with optimizing my code). Is it possible to create a method that returns necessary outerKeySelector (i => i.ItemId1, i => i.ItemId2 etc.) as func for Join that depends from ItemType ?
Thanks!
public class ItemModel
{
public long ItemId1 { get; set; }
public long ItemId2 { get; set; }
public long ItemId3 { get; set; }
public long ItemId4 { get; set; }
}
public class IdModel
{
public long Id { get; set; }
public decimal Quantity { get; set; }
}
public enum ItemType
{
Item1,
Item2,
Item3,
Item4
}
I believe it could be much shorter)
private static IEnumerable<IdModel> GetResult(IEnumerable<ItemModel> itemList, IEnumerable<IdModel> idList, ItemType itemType)
{
return itemType switch
{
ItemType.Item1 => itemList.Join(idList,
i => i.ItemId1,
j => j.Id,
(i, j) => new IdModel()
{
Id = j.Id,
Quantity = j.Quantity
}),
ItemType.Item2 => itemList.Join(idList,
i => i.ItemId2,
j => j.Id,
(i, j) => new IdModel()
{
Id = j.Id,
Quantity = j.Quantity
})
};
}
I wouldn't suggest shorter is necessarily more optimal, but I sometimes prefer shorter to more verbose anyway.
With a little preparation work creating a Dictionary<>
to map ItemType
s to accessor delegates, you can remove your switch
expression.
private static Dictionary<ItemType, Func<ItemModel,long>> ItemIdAccessMap = new() {
{ ItemType.Item1, (ItemModel item) => item.ItemId1 },
{ ItemType.Item2, (ItemModel item) => item.ItemId2 },
{ ItemType.Item3, (ItemModel item) => item.ItemId3 },
{ ItemType.Item4, (ItemModel item) => item.ItemId4 },
};
I prefer reversing the order of the Join
since you are throwing away the itemList
members that match anyway.
private static IEnumerable<IdModel> GetResult(IEnumerable<ItemModel> itemList, IEnumerable<IdModel> idList, ItemType itemType)
=> idList.Join(
itemList,
id => id.Id,
ItemIdAccessMap[itemType],
(id, item) => id
);
If you are concerned with having all ItemType
members being handled, you could use Reflection to create the delegates dynamically, at the expense of some startup runtime.