【发布时间】:2010-06-22 20:17:28
【问题描述】:
我想编写一个扩展方法来测试某个属性是否应用于方法调用,并且我想将该方法指定为 lambda 表达式。目前,我有以下(工作)方法,但我真的不喜欢这段代码的样子:
// Signature of my extension method:
public static bool HasAttribute<TAttribute, TDelegate>(this Expression<TDelegate> method)
// Usage (current code)
Expression<Func<AccountController, LogInModel, string, ActionResult>> mut = (c, m, s) => c.LogIn(m, s);
mut.HasAttribute<ExportModelStateAttribute, Func<AccountController, LogInModel, string, ActionResult>>().ShouldBeTrue();
如你所见,我必须指定委托类型两次,而且两次都不好看...我想要更像的东西
// Usage (if I had my way...)
var mut = (c, m, s) => c.LogIn(m, s);
mut.HasAttribute<ExportModelStateAttribute>().ShouldBeTrue();
但我意识到这可能有点过分了。
有什么方法可以重构掉当前代码中的类型参数?
我首先在那里有TDelegate 类型参数的原因是,我想使用它而不考虑方法签名和返回类型,并且取决于输入参数的数量以及所讨论的方法是否是void 或函数,TDelegate 需要变化。我不想对我测试的方法的每个输入参数数量都有一个不同的实现......
更新:
正如 Jay 在评论中指出的那样,我显然不需要在对 HasAttribute<> 的调用中指定 TDelegate 类型参数。现在的代码如下所示:
Expression<Func<AccountController, LogInModel, string, ActionResult>> mut = (c, m, s) => c.LogIn(m, s);
mut.HasAttribute<ExportModelStateAttribute>().ShouldBeTrue();
它好多了,但我仍然认为第一行相当混乱。会不会更好?
【问题讨论】:
-
为什么需要在
HasAttribute扩展方法中提供第二个类型参数? -
@Jay,你是对的——看来我没有。但是,我仍然觉得代码很丑陋。会不会更好?
-
@Jay,已经收集了新的事实:如果我确实提供了第二种类型的参数,那么一切正常。如果我不这样做,我的测试将失败(因为隐式提供的
TDelegate或Body属性都不是MethodCallExpression...)
标签: c# generics refactoring delegates inferred-type