Mor*_*iya 5 c# arguments args optional-parameters ambiguous
我有一个日志记录接口,我使用一些有用的扩展方法对其进行了扩展,以便我可以传递格式和参数列表,以避免每次调用该方法时都必须使用字符串格式。(它还帮助我遵循 FXCops 文化信息规则)
所以我可以打电话:
logger.Debug("Created {0} with id {1}",typeof(MyObject).Name ,myObject.Id);
Run Code Online (Sandbox Code Playgroud)
代替:
logger.Debug(string.Format("Created {0} with id {1}", typeof(MyObject).Name, myObject.Id));
Run Code Online (Sandbox Code Playgroud)
我现在发现自己处于一个有点棘手的情况,因为在日志中获取一些关于日志记录位置的信息(例如文件、方法和行号)会非常有帮助。这可能与整齐的实现[CallerMemberName],[CallerFilePath]和[CallerLineNumber]属性。
logger.Debug("Created {0} with id {1}", typeof(MyObject).Name, myObject.Id);
Run Code Online (Sandbox Code Playgroud)
然后会给我一个日志条目,例如:
“MyObjectProvider.cs,提供,第 50 行 | 创建的 MyObject,ID 为 1564”
这里的问题是方法签名看起来像这样:
public static void Debug(this ILogger logger, string format [CallerMemberName] string callerMemberName = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = 0, params object[] args)
Run Code Online (Sandbox Code Playgroud)
这是不可能的,因为[Caller*]属性使参数成为可选的,并且不适用于 args 参数。
我还尝试使用固定数量的字符串作为参数进行多个实现,如下所示:
public static void Debug(this ILogger logger, string format [CallerMemberName] string callerMemberName = "",string arg, string arg2 , ...etc... , [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = 0)
Run Code Online (Sandbox Code Playgroud)
但是后来我收到编译器错误,说“以下方法或属性之间的调用不明确”
我现在几乎已经放弃了这个问题,但我心里想,“也许 SO 可以为我找到解决方案”。所以这里是......是否可以同时使用params object[] args和[CallerFilePath]以任何方式或者有另一种方式来获得预期的结果?
您不能将两者组合在方法签名中。您可以做的是其中之一,然后传递null到您需要可选参数的地方,这对您有用吗?
Foo(s, null);
public void Foo(string s, params string[] sArray)
{
}
Foo(new string[] {""});
private static void Foo(string[] sArray, string s = "")
{
}
Run Code Online (Sandbox Code Playgroud)
或者
为什么不使用一个处理格式的类并将其设为可选呢?
public class LogArgs
{
private string _formatString;
private string[] _args;
public LogArgs(string formatString, params string[] args)
{
_formatString = formatString;
_args = args;
}
public override string ToString()
{
return string.Format(_formatString, _args);
}
}
public void Foo(string mandatory, LogArgs optionalParam = null)
{
//Do Stuff
}
Foo("", new LogArgs("{0} is formatted", ""));
Run Code Online (Sandbox Code Playgroud)