将通用参数转换为动态参数

问题描述 投票:0回答:1

我正在编写一个基于规则的模拟数据生成器。 但是为了节省时间,我决定使用一个动态容器来存储规则。

    public void AddGlobalRule<T, TProperty>(Expression<Func<T, TProperty>> property, Func<Faker, dynamic, dynamic, dynamic> rule)
        where T : class
    {
        var propertyName = ((MemberExpression)property.Body).Member.Name;
        this.AddRawRule(typeof(T), rule, propertyName);
    }

    public void AddRawRule(Type entityType, Func<Faker, dynamic, dynamic, dynamic> rule, string propertyName)
    {
        if (false == this._ruleMap.ContainsKey(entityType))
        {
            this._ruleMap.Add(entityType, new RuleSet());
        }

        var ruleset = this._ruleMap.Get(entityType);
        ruleset.Add((propertyName, rule));
    }

问题是这段代码没有intellisense,我真想把函数写成这样。

public void AddGlobalRule<T, TProperty>(Expression<Func<T, TProperty>> property, Func<Faker, T, T, TProperty> rule)
    where T : class
{
    var propertyName = ((MemberExpression)property.Body).Member.Name;
    var dynamicRule = rule as Func<Faker, dynamic, dynamic, dynamic>;
    this.AddRawRule(typeof(T), dynamicRule, propertyName);
}

为了清楚起见,编辑一下

如果我使用 Func<Faker, T, T, TProperty> rule 作为函数的输入,当我使用它时

 generator.AddGlobalRule<Employee, string>(x => x.Name, 
    (f, previous, current) => {
       //If I use Dynamic I don't have intellisense here
       return current.FirstName + current.LastName;
    })

但是当我尝试投递动态规则时,却是空的。

var dynamicRule = rule as Func<Faker, dynamic, dynamic, dynamic>;

我怎样才能投射到我的规则中,这样我就可以保留intellisense?

c# dynamic func
1个回答
1
投票

右边 铸造 Func<Faker, dynamic, dynamic, dynamic> 实际上与投向 Func<Faker, object, object, object>只是用动态分辨率。所以你不能这样做,因为输入到 Func 是 contravariant 而非 covariant (一个委托人把一个 arg 的 T 的参数,也不会接受 object).

(我会问自己,为什么你在地图中的存储与 dynamic 争论,而不是普通的 objects? 你真的是在动态地消耗这些吗?)

无论如何,你需要将你的 delegate 包裹在一些可以下传到所需类型的东西中,比如。

Func<Faker, dynamic, dynamic, dynamic> dynamicRule = (a, b, c) => rule(a, (T)b, (T)c);
© www.soinside.com 2019 - 2024. All rights reserved.