如果你只是写到控制台,即它是调试风格的输出,那么你想要的是最小的错字/复制粘贴错误的机会。
这在引擎盖下令人困惑,但在呼叫站点非常有效:
public static void WriteNameAndValue<T,TValue>(
this TextWriter tw, T t,
Expression<Func<T, TValue>> getter)
{
var memberExpression = getter.Body as MemberExpression;
if (memberExpression == null)
throw new ArgumentException("missing body!");
var member = memberExpression.Member;
tw.Write(member.Name);
tw.Write(": ");
if (member is FieldInfo)
{
tw.Write(((FieldInfo)member).GetValue(t));
}
else if (member is PropertyInfo)
{
tw.Write(((PropertyInfo)member).GetValue(t, null));
}
}
public static void WriteNameAndValueLine<T,TValue>(
this TextWriter tw, T t,
Expression<Func<T, TValue>> getter)
{
WriteNameAndValue<T,TValue>(tw, t, getter);
tw.WriteLine();
}
然后你可以写
t.Foo = "bar";
t.Bar = 32.5;
Console.Out.WriteNameAndValueLine(t, x => x.Foo);
Console.Out.WriteNameAndValueLine(t, x => x.Bar);
// output
// Foo: bar
// Bar: 32.5
如果您希望这在运行时通过资源更具可配置性并且考虑到本地化,您可以这样做,但如果这是可能的要求,我会考虑另一种更标准化的方法。
PS,如果您想花哨,可以将 FieldInfo/PropertyInfo 开关替换为
tw.Write(getter.Compile()(t));
然后您也可以在表达式中检查 MethodInfo (或允许任意 lambdas 并仅插入行号或其他一些通用文本。我建议不要沿着这条路线走,用法已经令人困惑,这也可能导致不需要的负载应该是一个简单的记录方法。