我在会话中存储了几个类。我希望能够在跟踪查看器中查看我的类属性的值。默认情况下,我只输入类型名称MyNamespace.MyClass。我想知道我是否覆盖 .ToString()方法并使用反射来遍历所有属性并构造一个类似的字符串...它会做的伎俩但只是想看看是否有已经存在的任何东西(特别是因为立即窗口具有此功能)它做同样的事情...即列出跟踪中的类属性值而不仅仅是类的名称。
答案 0 :(得分:3)
我相信这会有所帮助:C# object dumper
答案 1 :(得分:3)
你可以尝试这样的事情:
static void Dump(object o, TextWriter output)
{
if (o == null)
{
output.WriteLine("null");
return;
}
var properties =
from prop in o.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)
where prop.CanRead
&& !prop.GetIndexParameters().Any() // exclude indexed properties to keep things simple
select new
{
prop.Name,
Value = prop.GetValue(o, null)
};
output.WriteLine(o.ToString());
foreach (var prop in properties)
{
output.WriteLine(
"\t{0}: {1}",
prop.Name,
(prop.Value ?? "null").ToString());
}
}
当然,由于反射而效率不高......更好的解决方案是为每种特定类型动态生成和缓存转储器方法。
编辑:这是一个改进的解决方案,它使用Linq表达式为每种类型生成专门的转储器方法。稍微复杂一些;)
static class Dumper
{
private readonly static Dictionary<Type, Action<object, TextWriter>> _dumpActions
= new Dictionary<Type, Action<object, TextWriter>>();
private static Action<object, TextWriter> CreateDumper(Type type)
{
MethodInfo writeLine1Obj = typeof(TextWriter).GetMethod("WriteLine", new[] { typeof(object) });
MethodInfo writeLine1String2Obj = typeof(TextWriter).GetMethod("WriteLine", new[] { typeof(string), typeof(object), typeof(object) });
ParameterExpression objParam = Expression.Parameter(typeof(object), "o");
ParameterExpression outputParam = Expression.Parameter(typeof(TextWriter), "output");
ParameterExpression objVariable = Expression.Variable(type, "o2");
LabelTarget returnTarget = Expression.Label();
List<Expression> bodyExpressions = new List<Expression>();
bodyExpressions.Add(
// o2 = (<type>)o
Expression.Assign(objVariable, Expression.Convert(objParam, type)));
bodyExpressions.Add(
// output.WriteLine(o)
Expression.Call(outputParam, writeLine1Obj, objParam));
var properties =
from prop in type.GetProperties(BindingFlags.Instance | BindingFlags.Public)
where prop.CanRead
&& !prop.GetIndexParameters().Any() // exclude indexed properties to keep things simple
select prop;
foreach (var prop in properties)
{
bool isNullable =
!prop.PropertyType.IsValueType ||
prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
// (object)o2.<property> (cast to object to be passed to WriteLine)
Expression propValue =
Expression.Convert(
Expression.Property(objVariable, prop),
typeof(object));
if (isNullable)
{
// (<propertyValue> ?? "null")
propValue =
Expression.Coalesce(
propValue,
Expression.Constant("null", typeof(object)));
}
bodyExpressions.Add(
// output.WriteLine("\t{0}: {1}", "<propertyName>", <propertyValue>)
Expression.Call(
outputParam,
writeLine1String2Obj,
Expression.Constant("\t{0}: {1}", typeof(string)),
Expression.Constant(prop.Name, typeof(string)),
propValue));
}
bodyExpressions.Add(Expression.Label(returnTarget));
Expression<Action<object, TextWriter>> dumperExpr =
Expression.Lambda<Action<object, TextWriter>>(
Expression.Block(new[] { objVariable }, bodyExpressions),
objParam,
outputParam);
return dumperExpr.Compile();
}
public static void Dump(object o, TextWriter output)
{
if (o == null)
{
output.WriteLine("null");
}
Type type = o.GetType();
Action<object, TextWriter> dumpAction;
if (!_dumpActions.TryGetValue(type, out dumpAction))
{
dumpAction = CreateDumper(type);
_dumpActions[type] = dumpAction;
}
dumpAction(o, output);
}
}
用法:
Dumper.Dump(myObject, Console.Out);
答案 2 :(得分:1)
这是我使用的代码。我发现它非常有用,几乎是即时的。代码使用的是Newtonsoft JSON转换器。
[System.Obsolete("ObjectDump should not be included in production code.")]
public static void Dump(this object value)
{
try
{
System.Diagnostics.Trace.WriteLine(JsonConvert.SerializeObject(value, Formatting.Indented));
}
catch (Exception exception)
{
System.Diagnostics.Trace.WriteLine("Object could not be formatted. Does it include any interfaces? Exception Message: " + exception.Message);
}
}
将其添加到公共库,引用它并将其添加到using子句。可以通过键入YourObject.Dump()在即时窗口中使用(与在linqpad中完全相同)。
包括接口的类必须以不同方式处理,因为这只是一个JSON转换器。包含接口实现的类的解决方法是删除默认的空构造函数,并使用接口的特定实例实现构造函数。
我发现JSON是一种非常简单的阅读格式,并认为这种小方法非常适合调试。