【问题标题】:getting an error on casting object to system.Func<object>将对象转换为 system.Func<object> 时出错
【发布时间】:2021-02-01 15:47:59
【问题描述】:

我有下面的代码,我在其中循环材料并创建 osm 模型对象并将其添加到材料列表中(material vector),这工作正常。

由于重复的材料,我在这里添加了创建重复的 osm 模型对象。所以为了避免这种情况,我正在实现一个通用的具体类,它有一个常规字典来缓存对象,以及一个 Func 工厂参数,如果在缓存中找不到,则创建新项目

    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.FenestrationMaterial”转换为“system.Func”

如果我做错了,任何人都可以就如何克服这个错误或任何其他建议提出任何想法,将非常感谢我。

提前多谢

【问题讨论】:

  • 您的意思是将glazingMaterial.AddToOsm(model) 作为Func&lt;T&gt; createItem 传递给cacheObject.GetOrCreate() 方法吗?发生的事情是您传递的是该调用的 result

标签: c# .net generics caching .net-core


【解决方案1】:

试试这个

var material = cacheObject.GetOrCreate(glazingMaterial.Id, () => glazingMaterial.AddToOsm(model));

GetOrCreate 期望函数作为第二个参数,但你给它一个函数的结果

【讨论】:

    【解决方案2】:

    您将函数调用的结果而不是委托传递给cacheObject.GetOrCreate() - glazingMaterial.AddToOsm(model) 不是Func&lt;T&gt; createItem。全部更改如下:

    using var material = cacheObject.GetOrCreate(glazingMaterial.Id, 
                                                 () => glazingMaterial.AddToOsm(model));
    

    此更改通过 lambda 表达式创建了一个 匿名方法,也称为 工厂方法 - 这将满足 Func&lt;T&gt; createItem 参数, 前提是glazingMaterial.AddToOsm(model) 返回一个有效的T

    【讨论】:

    • 这里有一个问题,每次我进入 if 循环条件时,我都在检查“!_cache.ContainsKey(key)”键,您能否建议我为什么要创建每次都是新的。
    • 因为您的密钥是 class,它是一个 引用类型 - 您只是在比较对装箱值的引用而不是 Ids - 如果您的 @987654330 @ 是一个 int 你应该只使用它作为键,或者接受第二个通用参数。一般来说,你不应该使用object 作为键
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 2012-10-21
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多