Я пытаюсь создать гипотетическую систему с ресторанами, продуктами, опциями и идентификаторами продуктов.
У ресторана может быть два типа идентификаторов продуктов: целочисленные и строковые. Поэтому мне нужно это учитывать. Вот почему идентификатор продукта упаковывается для поддержки внешних систем, которые отправляют продукты со строковыми или целочисленными идентификаторами (некоторые интеграции хранят идентификаторы в формате UUID, а некоторые — в целочисленном формате).
У меня есть система доставки, которая получает любой ресторан, реализующий интерфейс (у которого также есть Product, Option и ProductId — все они должны реализовать свои соответствующие интерфейсы).
У меня есть сомнения относительно моего решения, потому что оно слишком много общего кода, который затрудняет написание (представьте, что вам придется написать такой код для более чем 20 ресторанов), а также содержит ошибку. Поэтому я не могу продолжить из-за ошибки.
В настоящее время я не думаю, что необходимо использовать класс адаптера для каждого ресторана (с приведениями внутри) или иметь система доставки, которая использует дженерики в определении класса (поскольку я могу получать рестораны во время выполнения - я не смогу создать систему доставки с соответствующими типами ресторанов - у меня просто нет их во время выполнения без отражения, и мне нужно избегать отражение любой ценой, потому что доставка будет осуществляться во время выполнения (а не запуска), а отражение не оправдано с точки зрения скорости и пропускной способности).
Я думаю, что основная проблема заключается в моем непонимании дженерики и способы их использования в сценариях реальных проектов. Можете ли вы мне помочь?
Вот код (также доступна ссылка на скрипт: https://dotnetfiddle.net/xzi10f):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IProductId { }
public interface IProductId : IProductId {
public TId GetIdValue();
}
public interface IOption {
public string GetName();
public float GetPrice();
}
public interface IProduct where TProductId : IProductId where TOption : IOption {
public TProductId GetId();
public string GetName();
public float GetPrice();
public void AddOption(TOption option);
public TOption[] GetOptions();
}
public interface IRestaurant
where TProductId : IProductId
where TOption : IOption
where TProduct : IProduct {
public void AddProduct(TProduct product);
public TProduct[] GetProducts();
}
// Real implementation
public abstract class FastfoodRestaurantOption(string name, float price) : IOption {
private readonly string name = name;
private readonly float price = price;
public string GetName() => name;
public float GetPrice() => price;
}
public class BurgerOption(string name, float price) : FastfoodRestaurantOption(name, price) {
private bool fried = false;
public bool Fry() => fried = true;
public bool IsFried() => fried;
}
public class FastfoodRestaurantProductId : IProductId {
public required string Id { private get; init; }
public string GetIdValue() => Id;
}
public class Burger : IProduct {
private float discount = 1;
public float GetPrice()
=> (10 + (GetOptions().Sum(o => o.GetPrice()))) * discount;
public string GetName() => "Burger";
public void ApplyDiscount(float discount) => this.discount = discount;
private readonly List options = [];
public void AddOption(FastfoodRestaurantOption option) {
var burgerOption = (BurgerOption)option;
if (burgerOption.IsFried()) Console.WriteLine($"Burger option named {burgerOption.GetName()} is fried!");
options.Add(burgerOption);
}
public FastfoodRestaurantOption[] GetOptions() => [.. options.Cast()];
public FastfoodRestaurantProductId GetId() {
return new FastfoodRestaurantProductId {
Id = "some_product_id"
};
}
}
public class FastfoodRestaurant
: IRestaurant {
private bool discountDay = false;
public void MakeDiscountDay() => discountDay = true;
private readonly List products = [];
public void AddProduct(IProduct product) {
if (discountDay) {
if (product is Burger burger) {
Console.WriteLine("Product is burger applying discount!");
burger.ApplyDiscount(0.8f);
}
}
products.Add(product);
}
public IProduct[] GetProducts() => products.ToArray();
}
public class ProductShipper {
public void ShipProductsFromRestaurant(
IRestaurant restaurant
) {
foreach (var product in restaurant.GetProducts()) {
var id = product.GetId();
if (id is IProductId stringId) {
Console.WriteLine($"Product ID is STRING: {stringId.GetIdValue()}. Storing in one table...");
} else if (id is IProductId intId) {
Console.WriteLine($"Product ID is INT: {intId.GetIdValue()}. Storing in another table...");
}
Console.WriteLine($"Shipping product named {product.GetName()} with price: {product.GetPrice()}");
foreach (var option in product.GetOptions()) {
Console.WriteLine(
$"Product has option: {option.GetName()}"
);
}
}
}
}
internal static class PlaygroundGenerics {
public static void Main() {
var fastfoodRestaurant = new FastfoodRestaurant();
var burger = new Burger();
var lettuce = new BurgerOption("Lettuce", 10);
lettuce.Fry();
var cheese = new BurgerOption("Cheese", 20);
burger.AddOption(lettuce);
burger.AddOption(cheese);
fastfoodRestaurant.AddProduct(burger);
var shipper = new ProductShipper();
shipper.ShipProductsFromRestaurant(fastfoodRestaurant); // Error here. cannot convert from 'FastfoodRestaurant' to 'IRestaurant'
}
}
public static class Program {
public static int Main() {
PlaygroundGenerics.Main();
return 0;
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... ng-for-dec
Как правильно использовать дженерики для практики программирования на основе интерфейсов для разделения частей системы? ⇐ C#
Место общения программистов C#
1727285748
Anonymous
Я пытаюсь создать гипотетическую систему с ресторанами, продуктами, опциями и идентификаторами продуктов.
У ресторана может быть два типа идентификаторов продуктов: целочисленные и строковые. Поэтому мне нужно это учитывать. Вот почему идентификатор продукта упаковывается для поддержки внешних систем, которые отправляют продукты со строковыми или целочисленными идентификаторами (некоторые интеграции хранят идентификаторы в формате UUID, а некоторые — в целочисленном формате).
У меня есть система доставки, которая получает любой ресторан, реализующий интерфейс (у которого также есть Product, Option и ProductId — все они должны реализовать свои соответствующие интерфейсы).
У меня есть сомнения относительно моего решения, потому что оно слишком много общего кода, который затрудняет написание (представьте, что вам придется написать такой код для более чем 20 ресторанов), а также содержит ошибку. Поэтому я не могу продолжить из-за ошибки.
В настоящее время я не думаю, что необходимо использовать класс адаптера для каждого ресторана (с приведениями внутри) или иметь система доставки, которая использует дженерики в определении класса (поскольку я могу получать рестораны во время выполнения - я не смогу создать систему доставки с соответствующими типами ресторанов - у меня просто нет их во время выполнения без отражения, и мне нужно избегать отражение любой ценой, потому что доставка будет осуществляться во время выполнения (а не запуска), а отражение не оправдано с точки зрения скорости и пропускной способности).
Я думаю, что основная проблема заключается в моем непонимании дженерики и способы их использования в сценариях реальных проектов. Можете ли вы мне помочь?
Вот код (также доступна ссылка на скрипт: https://dotnetfiddle.net/xzi10f):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IProductId { }
public interface IProductId : IProductId {
public TId GetIdValue();
}
public interface IOption {
public string GetName();
public float GetPrice();
}
public interface IProduct where TProductId : IProductId where TOption : IOption {
public TProductId GetId();
public string GetName();
public float GetPrice();
public void AddOption(TOption option);
public TOption[] GetOptions();
}
public interface IRestaurant
where TProductId : IProductId
where TOption : IOption
where TProduct : IProduct {
public void AddProduct(TProduct product);
public TProduct[] GetProducts();
}
// Real implementation
public abstract class FastfoodRestaurantOption(string name, float price) : IOption {
private readonly string name = name;
private readonly float price = price;
public string GetName() => name;
public float GetPrice() => price;
}
public class BurgerOption(string name, float price) : FastfoodRestaurantOption(name, price) {
private bool fried = false;
public bool Fry() => fried = true;
public bool IsFried() => fried;
}
public class FastfoodRestaurantProductId : IProductId {
public required string Id { private get; init; }
public string GetIdValue() => Id;
}
public class Burger : IProduct {
private float discount = 1;
public float GetPrice()
=> (10 + (GetOptions().Sum(o => o.GetPrice()))) * discount;
public string GetName() => "Burger";
public void ApplyDiscount(float discount) => this.discount = discount;
private readonly List options = [];
public void AddOption(FastfoodRestaurantOption option) {
var burgerOption = (BurgerOption)option;
if (burgerOption.IsFried()) Console.WriteLine($"Burger option named {burgerOption.GetName()} is fried!");
options.Add(burgerOption);
}
public FastfoodRestaurantOption[] GetOptions() => [.. options.Cast()];
public FastfoodRestaurantProductId GetId() {
return new FastfoodRestaurantProductId {
Id = "some_product_id"
};
}
}
public class FastfoodRestaurant
: IRestaurant {
private bool discountDay = false;
public void MakeDiscountDay() => discountDay = true;
private readonly List products = [];
public void AddProduct(IProduct product) {
if (discountDay) {
if (product is Burger burger) {
Console.WriteLine("Product is burger applying discount!");
burger.ApplyDiscount(0.8f);
}
}
products.Add(product);
}
public IProduct[] GetProducts() => products.ToArray();
}
public class ProductShipper {
public void ShipProductsFromRestaurant(
IRestaurant restaurant
) {
foreach (var product in restaurant.GetProducts()) {
var id = product.GetId();
if (id is IProductId stringId) {
Console.WriteLine($"Product ID is STRING: {stringId.GetIdValue()}. Storing in one table...");
} else if (id is IProductId intId) {
Console.WriteLine($"Product ID is INT: {intId.GetIdValue()}. Storing in another table...");
}
Console.WriteLine($"Shipping product named {product.GetName()} with price: {product.GetPrice()}");
foreach (var option in product.GetOptions()) {
Console.WriteLine(
$"Product has option: {option.GetName()}"
);
}
}
}
}
internal static class PlaygroundGenerics {
public static void Main() {
var fastfoodRestaurant = new FastfoodRestaurant();
var burger = new Burger();
var lettuce = new BurgerOption("Lettuce", 10);
lettuce.Fry();
var cheese = new BurgerOption("Cheese", 20);
burger.AddOption(lettuce);
burger.AddOption(cheese);
fastfoodRestaurant.AddProduct(burger);
var shipper = new ProductShipper();
shipper.ShipProductsFromRestaurant(fastfoodRestaurant); // Error here. cannot convert from 'FastfoodRestaurant' to 'IRestaurant'
}
}
public static class Program {
public static int Main() {
PlaygroundGenerics.Main();
return 0;
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79024158/how-to-properly-utilize-generics-to-practice-interface-based-programming-for-dec[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия