【发布时间】:2014-12-30 09:17:43
【问题描述】:
我正在尝试将 C# 5.0 调用方信息与 C# params 关键字结合起来。目的是为日志框架创建一个包装器,我们希望日志器像 String.Format 一样格式化文本。在以前的版本中,该方法如下所示:
void Log(
string message,
params object[] messageArgs = null);
我们这样称呼它:
log.Log("{0}: I canna do it cap'n, the engines can't handle warp {1}!",
"Scotty", warpFactor);
现在,我们要捕获来电者信息并将其记录下来。于是签名就变成了:
void Log(
string message,
params object[] messageArgs,
[CallerMemberName] string sourceMemberName = null);
这不会编译,因为参数必须是最后一个参数。所以我试试这个:
void Log(
string message,
[CallerMemberName] string sourceMemberName = null,
params object[] messageArgs);
有没有一种方法可以在不提供 sourceMembername 或将 messageArgs 参数显式分配为命名参数的情况下调用它?这样做违背了 params 关键字的目的:
// params is defeated:
log.Log("message",
messageArgs: new object[] { "Scotty", warpFactor });
// CallerMemberName is defeated:
log.Log("message", null,
"Scotty", warpFactor);
有没有办法做到这一点?似乎传递调用者信息的“hacky”方式排除了使用 params 关键字。如果 C# 编译器识别出调用者成员信息参数根本不是 真正 参数,那就太棒了。我认为没有必要明确地传递它们。
我的备份将是跳过 params 关键字,调用者将不得不使用最后一个示例中的长签名。
【问题讨论】:
-
你不能用不包含 sourceMemberName 参数的普通旧重载来做吗?
-
@Louis:关键是他们希望方法包含该参数。由于
[CallerMemberName]属性,它会由编译器自动填充。 -
我asked this question previously 并收到了一些有用的建议。我对这个问题的回答包括我最终采取的解决这个限制的方法。
-
Dan:我想我浏览了所有标记为 callermembername 的问题。抱歉,我错过了那个。
标签: c# params-keyword callermembername