在Visual Studio中,是否可以自定义在调试器中检查属性时的显示顺序?
这是一个类的例子,我真的很喜欢StartDate和EndDate彼此相邻,即使它们按字母顺序分开。
其他调试器选项可以通过DebuggerDisplayAttribute
等属性进行自定义,因此我希望DisplayOrder能够存在另一个这样的属性。
[DebuggerDisplay("{Name}")]
public class Rule
{
public string Name;
public int MaxAge;
public DateTime StartDate;
public DateTime EndDate;
}
在理想世界中,我希望能够按照我在类中定义的顺序在检查器中对属性进行排序(即使这需要设置调试器顺序属性)逐步增加每个属性)所以显示将如下所示:
答案 0 :(得分:4)
Pinnable Properties 是目前可行的方法,因为您可以使用数据提示内的 按钮按正确顺序固定属性。
但是,在更通用、可重用的方法中,[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
属性可用于有序属性名称和值对的数组。这使调试视图能够“展平”数组根,以正确的顺序列出属性。
进一步扩展 KyleMit's answer,并使用反射加载成员和字段列表,使这样的调试视图可重用:
[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
数据提示如下所示:
答案 1 :(得分:2)
只需将JCL's suggestion上的球用完就可以使用#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
}
看起来像这样:
这会将信息一起呈现,但仍会向检查员添加噪音。
答案 2 :(得分:1)
您可以右键单击变量和“添加监视”并将其按顺序放置。
答案 3 :(得分:1)
只是为了在JCL's suggestion上运行球以使用DebuggerTypeProxyAttribute
,您可以添加内部类或公共类作为调试视图的容器
您可以使用数字强制在调试器视图类上对属性进行排序,而无需更改API或运行时代码的性能。
以下是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;
}
}
}
在调试器中看起来像这样:
它不是世界上最干净的东西,但确实做了一点。