#c# #.net #generics #caching #.net-core
#c# #.net #общие #кэширование #.net-ядро
Вопрос:
У меня есть приведенный ниже код, в котором я перебираю материалы и создаю объект модели osm и добавляю его в список материалов ( material vector
) , и это работает нормально.
Здесь я добавляю создание повторяющихся объектов модели osm из-за повторяющихся материалов. поэтому, чтобы избежать этого, я реализую общий конкретный класс, который имеет обычный словарь для кэширования объектов и параметр Func factory для создания новых элементов, если они не найдены в кэше
public Construction AddToOsm(Model model)
{
if (model is null)
{
throw new ArgumentNullException(nameof(model));
}
var construction = new Construction(model);
construction.setName($"{this.Name} - {this.AshraeClimateZone?.Name}");
using var materials = new MaterialVector();
foreach (var glazingMaterial in this.Layers)
{
if (glazingMaterial != default)
{
using var material = glazingMaterial.AddToOsm(model); // here i am creating duplicate osm model objects
materials.Add(material);
}
}
construction.setLayers(materials);
return construction;
}
и ниже приведен класс, в котором я реализую эту проверку для создания или извлечения объектов
public class CacheObject<T>
{
private readonly Dictionary<object, T> _cache = new Dictionary<object, T>();
public T GetOrCreate(object key, Func<T> createItem)
{
if (!_cache.ContainsKey(key))
{
_cache[key] = createItem();
}
return _cache[key];
}
}
и затем я использую вышеуказанный метод, как показано ниже
using var materials = new MaterialVector();
foreach (var glazingMaterial in this.Layers)
{
if (glazingMaterial != default)
{
var cacheObject = new CacheObject<FenestrationMaterial>();
using var material = cacheObject.GetOrCreate(glazingMaterial.Id, glazingMaterial.AddToOsm(model)); // getting an object casting exception
// using var material = glazingMaterial.AddToOsm(model);
materials.Add(material);
}
}
Я получаю ошибку в этой строке
using var material = cacheObject.GetOrCreate(glazingMaterial.Id, glazingMaterial.AddToOsm(model));
и ошибка
не удается преобразовать из ‘OpenStudio.Перенос материала «в» систему.Функция ‘
Не мог бы кто-нибудь, пожалуйста, предложить какие-либо идеи по этому поводу, как преодолеть эту ошибку или любое другое предложение, если я делаю неправильно, было бы очень благодарно мне.
заранее большое спасибо
Комментарии:
1. Вы имели в виду передать
glazingMaterial.AddToOsm(model)
какFunc<T> createItem
cacheObject.GetOrCreate()
метод to? Происходит то, что вместо этого вы передаете результат этого вызова
Ответ №1:
Попробуйте это
var material = cacheObject.GetOrCreate(glazingMaterial.Id, () => glazingMaterial.AddToOsm(model));
GetOrCreate
ожидает функцию в качестве второго аргумента, но вместо этого вы даете ей результат функции
Ответ №2:
Вы передаете результат вызова функции вместо делегата cacheObject.GetOrCreate()
— glazingMaterial.AddToOsm(model)
это не a Func<T> createItem
. Измените все следующим образом:
using var material = cacheObject.GetOrCreate(glazingMaterial.Id,
() => glazingMaterial.AddToOsm(model));
Это изменение создает анонимный метод с помощью лямбда-выражения, также известного как фабричный метод — это удовлетворит Func<T> createItem
параметру, при условии, что glazingMaterial.AddToOsm(model)
возвращает допустимый T
Комментарии:
1. здесь возникает проблема, каждый раз, когда я захожу в условие цикла if, где я проверяю наличие «!_cache . Содержит ключ «Key (key)», и не могли бы вы предложить какую-либо идею, почему я каждый раз создаю новый.
2. Поскольку ваш ключ — это a
class
, который является ссылочным типом — вы просто сравниваете ссылки со значениями в штучной упаковке вместоId
s — если у васid
есть anint
, вы должны просто использовать это как ключ или использовать второй общий параметр. Как правило, вы никогда не должны использоватьobject
в качестве ключа