在 Visual Studio 调试器中以自定义顺序显示属性
Display Properties in Custom Order in Visual Studio Debugger
在 Visual Studio 中,是否可以自定义在调试器中检查时属性的显示顺序?
这是一个 class 的示例,我真的希望 StartDate 和 EndDate 彼此相邻出现,即使它们是按字母顺序分开的。
其他调试器选项可通过 DebuggerDisplayAttribute
等属性自定义,因此我希望 DisplayOrder 存在另一个此类属性。
[DebuggerDisplay("{Name}")]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
}
在 理想世界 中,我希望能够按照我在 class 上定义的顺序在检查器中对属性进行排序(即使这需要在每个 属性) 上递增地设置调试器顺序属性,因此显示如下所示:
您可以右键单击变量并 'Add Watch' 并将它们按顺序放置在那里。
只是为了 运行 在 to use DebuggerTypeProxyAttribute
上出球,你可以添加一个内部 class 或 public class 作为容器调试视图
您可以使用数字在调试器视图 class 上强制对属性进行排序,而无需更改 API 或 运行 时间代码的性能。
下面是 class 使用 DebuggerTypeProxy 时的样子:
[DebuggerDisplay("{Name}")]
[DebuggerTypeProxy(typeof (RuleDebugView))]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
internal class RuleDebugView
{
public string _1_Name;
public int _2_MaxAge;
public DateTime _3_StartDate;
public DateTime _4_EndDate;
public RuleDebugView(Rule rule)
{
this._1_Name = rule.Name;
this._2_MaxAge = rule.MaxAge;
this._3_StartDate = rule.StartDate;
this._4_EndDate = rule.EndDate;
}
}
}
在调试器中看起来像这样:
这不是世界上最干净的东西,但它确实起到了一点作用。
只是 运行 在 to use #if DEBUG
上用计算 属性 出球。如果你想在调试器中获得一些额外的信息,你可以只在调试模式下添加一个字段,如下所示:
[DebuggerDisplay("{Name}")]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
#if DEBUG
private string DateRange
{
get { return StartDate.ToString("dd/MM/yyyy") + " - "+
EndDate.ToString("dd/MM/yyyy");
}
}
#endif
}
看起来像这样:
这会同时显示信息,但仍会给检查员增加干扰。
Pinnable Properties in VS2019+ are a way to go currently, since you can pin your properties in correct order using the 数据提示内的按钮。
但是,在更通用、可重用的方法中,[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
属性可用于有序的 属性 名称和值对数组。这使调试视图能够 'flatten' 数组根,以正确的顺序列出属性。
进一步扩展 ,并使用反射加载成员和字段列表,使此类调试视图可重用:
[DebuggerDisplay("{Name}")]
[DebuggerTypeProxy(typeof(OrderedPropertiesView))]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
}
public class OrderedPropertiesView
{
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public SimpleProperty[] Properties { get; }
public OrderedPropertiesView(object input)
{
this.Properties = input.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Select(prop => new SimpleProperty(prop, input))
.ToArray();
}
[DebuggerDisplay("{Value}", Name = "{PropertyName,nq}")]
public class SimpleProperty
{
public SimpleProperty(MemberInfo member, object input)
{
this.Value = GetValue(member, input);
this.PropertyName = member.Name;
}
private object GetValue(MemberInfo member, object input)
{
switch (member)
{
case FieldInfo fi: return fi.GetValue(input);
case PropertyInfo pi: return pi.GetValue(input);
default: return null;
}
}
public object Value { get; internal set; }
public string PropertyName { get; internal set; }
}
}
在调试器中看起来像这样:
反射可能无法保证属性和字段的顺序,但由于视图仅用于调试目的,因此应该足够了。如果没有,可以手动构造 Properties
数组,限制可重用性。在任何一种情况下,Properties
都不是真正的属性,因此扩展 SimpleProperty
数据提示如下所示:
请注意,属性 检查器 只能在扩展的 SimpleProperty.Value
中使用,这可能会带来不便。
在 Visual Studio 中,是否可以自定义在调试器中检查时属性的显示顺序?
这是一个 class 的示例,我真的希望 StartDate 和 EndDate 彼此相邻出现,即使它们是按字母顺序分开的。
其他调试器选项可通过 DebuggerDisplayAttribute
等属性自定义,因此我希望 DisplayOrder 存在另一个此类属性。
[DebuggerDisplay("{Name}")]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
}
在 理想世界 中,我希望能够按照我在 class 上定义的顺序在检查器中对属性进行排序(即使这需要在每个 属性) 上递增地设置调试器顺序属性,因此显示如下所示:
您可以右键单击变量并 'Add Watch' 并将它们按顺序放置在那里。
只是为了 运行 在 DebuggerTypeProxyAttribute
上出球,你可以添加一个内部 class 或 public class 作为容器调试视图
您可以使用数字在调试器视图 class 上强制对属性进行排序,而无需更改 API 或 运行 时间代码的性能。
下面是 class 使用 DebuggerTypeProxy 时的样子:
[DebuggerDisplay("{Name}")]
[DebuggerTypeProxy(typeof (RuleDebugView))]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
internal class RuleDebugView
{
public string _1_Name;
public int _2_MaxAge;
public DateTime _3_StartDate;
public DateTime _4_EndDate;
public RuleDebugView(Rule rule)
{
this._1_Name = rule.Name;
this._2_MaxAge = rule.MaxAge;
this._3_StartDate = rule.StartDate;
this._4_EndDate = rule.EndDate;
}
}
}
在调试器中看起来像这样:
这不是世界上最干净的东西,但它确实起到了一点作用。
只是 运行 在 #if DEBUG
上用计算 属性 出球。如果你想在调试器中获得一些额外的信息,你可以只在调试模式下添加一个字段,如下所示:
[DebuggerDisplay("{Name}")]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
#if DEBUG
private string DateRange
{
get { return StartDate.ToString("dd/MM/yyyy") + " - "+
EndDate.ToString("dd/MM/yyyy");
}
}
#endif
}
看起来像这样:
这会同时显示信息,但仍会给检查员增加干扰。
Pinnable Properties in VS2019+ are a way to go currently, since you can pin your properties in correct order using the
但是,在更通用、可重用的方法中,[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
属性可用于有序的 属性 名称和值对数组。这使调试视图能够 'flatten' 数组根,以正确的顺序列出属性。
进一步扩展
[DebuggerDisplay("{Name}")]
[DebuggerTypeProxy(typeof(OrderedPropertiesView))]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
}
public class OrderedPropertiesView
{
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public SimpleProperty[] Properties { get; }
public OrderedPropertiesView(object input)
{
this.Properties = input.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Select(prop => new SimpleProperty(prop, input))
.ToArray();
}
[DebuggerDisplay("{Value}", Name = "{PropertyName,nq}")]
public class SimpleProperty
{
public SimpleProperty(MemberInfo member, object input)
{
this.Value = GetValue(member, input);
this.PropertyName = member.Name;
}
private object GetValue(MemberInfo member, object input)
{
switch (member)
{
case FieldInfo fi: return fi.GetValue(input);
case PropertyInfo pi: return pi.GetValue(input);
default: return null;
}
}
public object Value { get; internal set; }
public string PropertyName { get; internal set; }
}
}
在调试器中看起来像这样:
反射可能无法保证属性和字段的顺序,但由于视图仅用于调试目的,因此应该足够了。如果没有,可以手动构造 Properties
数组,限制可重用性。在任何一种情况下,Properties
都不是真正的属性,因此扩展 SimpleProperty
数据提示如下所示:
请注意,属性 检查器 SimpleProperty.Value
中使用,这可能会带来不便。