我正在编写一个基于规则的模拟数据生成器。 但是为了节省时间,我决定使用一个动态容器来存储规则。
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?
右边 铸造 Func<Faker, dynamic, dynamic, dynamic>
实际上与投向 Func<Faker, object, object, object>
只是用动态分辨率。所以你不能这样做,因为输入到 Func
是 contravariant 而非 covariant (一个委托人把一个 arg 的 T
的参数,也不会接受 object
).
(我会问自己,为什么你在地图中的存储与 dynamic
争论,而不是普通的 object
s? 你真的是在动态地消耗这些吗?)
无论如何,你需要将你的 delegate 包裹在一些可以下传到所需类型的东西中,比如。
Func<Faker, dynamic, dynamic, dynamic> dynamicRule = (a, b, c) => rule(a, (T)b, (T)c);