Вопрос связан с финансовыми продуктами, процентными ставками и двумя свойствами, которые определяют, какой интерес представляет определенный продукт. Но я думаю, что фрукты и корзины легче визуализировать для этого.
Во-первых, у нас есть плод. Фрукты могут иметь определенный размер (маленький, средний, большой) и цвет (красный, зеленый, синий). Это будут два разных перечисления. Корзины будут содержать все виды фруктов, но ни один из них не будет идентичен по цвету или форме. Но каждая комбинация будет в корзине. Поскольку у нас есть три размера и три цвета, мы получим 9 кусочков фруктов в каждой корзине. Если бы у нас было 4 цвета, у нас получилось бы 12 штук.
Мы храним информацию о корзине в корзине. В каждой корзине есть Словарь < {Размер, Цвет}, Фрукты > , который определяет все кусочки фруктов в корзине. Однако этот словарь не может быть полностью заполнен, и в этом случае все остальные комбинации являются яблоками. Словарь содержит только плоды другого рода. (Хотя они тоже могут содержать яблоки.) Рядом с яблоками у нас также есть груши и бананы. Да, они могут быть красными, но я бы подумал, какая краска была использована, чтобы сделать их красными. Помните, это просто для визуализации проблемы.: -)
Во всяком случае, теперь у меня есть список корзин с корзиной список фруктов. Яблоки по умолчанию, груши или бананы, если они находятся в словаре. Но мне нужно посмотреть на информацию под другим углом.
Мне нужно преобразовать эту структуру в список фруктов и фруктов в корзины, где их можно найти, а также размеры и цвета конкретных фруктов. Таким образом, бананы находятся в корзине 1 ({маленький, желтый}, {маленький, красный}, {средний, красный}), корзина 3 (...), корзина 4, 8 и 10. То же самое с грушами, t иметь желтую грушу в корзине 1, так как она уже определена для банана.
У меня есть большое преимущество: ни одна из этих структур еще не определена! Тем не менее, мне нужен вид корзины как способ предоставления информации процессу преобразования. И мне нужен вид Fruit для дальнейших вычислений, так как мне нужно сделать дополнительную математику, основанную только на самом плоде, а не на их размере или цвете или корзине, где они находятся...
Итак, любые хорошие предложения для структуры до и после преобразования и как сделать само преобразование, используя Linq в С#?
И мне нужно убедить руководство сделать этот шаг, потому что они боятся, что он много работает, становится нечитаемым или будет трудно поддерживать.
Ну, как только я начал, мне пришлось написать весь код. Может быть, это не решает вашу основную проблему, но я думаю, что она прибивает корзину для фруктов.
public enum FruitSize{Small, Medium, Large}
public enum FruitColor {Red, Green, Blue}
// immutable struct is important for use as dictionary keys
public struct FruitDescription
{
readonly FruitSize _size;
public FruitSize Size {get{return _size;}}
readonly FruitColor _color;
public FruitColor Color { get { return _color; } }
public FruitDescription(FruitSize size, FruitColor color)
{
_size = size;
_color = color;
}
}
//abstract parent class ...
public abstract class Fruit
{ public FruitDescription Description {get;set;} }
//... and children
public class Apple : Fruit{}
public class Banana : Fruit{}
public class Pear : Fruit{}
public class Basket
{
private Dictionary<FruitDescription, Fruit> internalFruits =
new Dictionary<FruitDescription, Fruit>();
public void AddFruit(Fruit addme)
{
internalFruits[addme.Description] = addme;
}
public IEnumerable<FruitDescription> AllDescriptions()
{
foreach (FruitSize size in Enum.GetValues(typeof(FruitSize)))
{
foreach (FruitColor color in Enum.GetValues(typeof(FruitColor)))
{
FruitDescription desc = new FruitDescription(size, color);
yield return desc;
}
}
}
public Apple GetDefaultApple(FruitDescription desc)
{
return new Apple() { Description = desc };
}
public IEnumerable<Fruit> GetFruits()
{
IEnumerable<Fruit> result = AllDescriptions()
.Select(desc =>
internalFruits.ContainsKey(desc) ?
internalFruits[desc] :
GetDefaultApple(desc));
return result;
}
}
public class Pair<T, U>
{
public T First { get; set; }
public U Second { get; set; }
}
public class TestClass
{
public static void Test()
{
Basket b1 = new Basket();
b1.AddFruit(new Banana() { Description =
new FruitDescription(FruitSize.Medium, FruitColor.Blue) });
b1.AddFruit(new Banana() { Description =
new FruitDescription(FruitSize.Medium, FruitColor.Green) });
Basket b2 = new Basket();
b2.AddFruit(new Pear() { Description =
new FruitDescription(FruitSize.Medium, FruitColor.Green) });
List<Basket> source = new List<Basket>();
source.Add(b1);
source.Add(b2);
//the main event - a query.
List<Pair<Fruit, Basket>> result =
(
from basket in source
from fruit in basket.GetFruits()
select new Pair<Fruit, Basket>()
{ First = fruit, Second = basket }
).ToList();
//a second results structure for fun
ILookup<Type, Basket> resultByType = result.ToLookup
(
p => p.First.GetType(),
p => p.Second
);
Console.WriteLine("Number of fruit: {0}",
result.Count);
Console.WriteLine("Number of apples: {0}",
resultByType[typeof(Apple)].Count());
Console.WriteLine("Number of baskets with apples: {0}",
resultByType[typeof(Apple)].Distinct().Count());
Console.WriteLine("Number of bananas: {0}",
resultByType[typeof(Banana)].Count());
Console.WriteLine("Number of baskets with bananas: {0}",
resultByType[typeof(Banana)].Distinct().Count());
}
}
С этими результатами:
Number of fruit: 18
Number of apples: 15
Number of baskets with apples: 2
Number of bananas: 2
Number of baskets with bananas: 1