【问题标题】:Using extension methods in [DebuggerDisplay] Attribute在 [DebuggerDisplay] 属性中使用扩展方法
【发布时间】:2011-04-09 10:01:54
【问题描述】:

属性 [DebuggerDisplay] (Using DebuggerDisplayAttribute) 允许在 VS 2010/2008 的调试器中定义显示。通过修改 AutoExp.cs/.dll,我什至可以覆盖系统类型和 3rd 方类型的显示,例如

[assembly: DebuggerDisplay (@"\{Name = {Name} FullName = {FullName}}", Target = typeof (Type))]

在内花括号中,我可以引用字段、属性和方法。是否可以参考扩展方法

例如,我尝试显示较短的类型名称,例如$SCG.Dictionary 而不是 System.Collections.Generic.Dictionary。我将此添加到 AutoExp.cs:

using DbgDisp;

[assembly: DebuggerDisplay (@"\{Name = {Name} ShortName = {ShortName()}}", Target = typeof (Type))]

namespace DbgDisp {
  public static class Ext {
    public static string ShortName (this Type t) { return string.Format ("[{0}]", t.Name); }
  } // Ext
} // DbgDisp

但调试器抱怨:当前上下文中不存在名称“ShortName”。

是我遗漏了什么,还是无法在那里使用扩展方法?

我知道我可以覆盖 ToString (),但这仅对我自己的类型有帮助。

【问题讨论】:

  • 当然,在调试显示上下文中执行我自己的代码的其他一些聪明的方法也会很有趣:)
  • 这帮助我创建了一个用于调试的自定义显示字符串。可以对密封类使用扩展。根据网站政策,seesharpers 的答案应在此处标记为已接受的答案:meta.stackexchange.com/questions/62252/…

标签: c# visual-studio-2010 extension-methods debuggervisualizer debuggerdisplay


【解决方案1】:

其实你可以使用扩展方法传递 this 作为参数

[assembly: DebuggerDisplay(@"NetGuid = {ToString()} OracleGuid = {GuidExtensions.ToVarChar(this)}", Target = typeof(Guid))]
public static class GuidExtensions
{
    public static string ToVarChar(this Guid guid)
    {
        var newBytes = new byte[16];
        var oldBytes = guid.ToByteArray();
        for (var i = 8; i < 16; i++)
            newBytes[i] = oldBytes[i];

        newBytes[3] = oldBytes[0];
        newBytes[2] = oldBytes[1];
        newBytes[1] = oldBytes[2];
        newBytes[0] = oldBytes[3];
        newBytes[5] = oldBytes[4];
        newBytes[4] = oldBytes[5];
        newBytes[6] = oldBytes[7];
        newBytes[7] = oldBytes[6];

        return new Guid(newBytes).ToString("N").ToUpper();
    }    
}

【讨论】:

  • 非常感谢,这非常有效(至少在 VS2017 中)。其他人注意:您的 [assembly: 属性未在任何命名空间中定义,因此您必须完全指定类型的命名空间。即MyCompany.MyProduct.Utils.GuidExtensions.ToVarChar(this)
【解决方案2】:

简而言之,没有。出于同样的原因,扩展方法不适用于dynamic,即从只是方法名称,没有办法知道using指令是有效的,因此扩展方法是候选者。完全有可能出现使用不同的using 指令会更改可用方法的情况,因此让它尝试猜测没有任何好处。

您必须将自己限制为常规方法,除非字符串允许您明确指定类的静态方法,即DbgDisp.Ext.ShortName(foo)

【讨论】:

  • 谢谢,马克。不,显式方法名称DbgDisp.Ext.ShortName 也不起作用。我认为使用扩展方法潜入类型很聪明,但是当 AutoExp 被编译时,它只是复制字符串文字。我想稍后,在调试时,会评估字符串文字,然后调试器使用反射来查找方法(type.GetMethods ())。如果它看起来不在类型之外,它就找不到我的方法。所以我猜错误消息中提到的上下文就是类型本身。
  • 但是,可以在 AutoExp 中将DebuggerTypeProxy 属性添加到第 3 方和系统类型,但这可能是另一个问题的解决方案 :)
  • 这个答案在技术上并没有错,但是当有办法在这里实现他们想要做的事情时,它会不必要地阻止人们。您可以在另一种类型(扩展或其他)上定义静态方法,并使用它为您无法控制的类型提供调试器显示字符串。您只需完全限定类型/方法并将this 作为参数传递。见seesharper's answer
【解决方案3】:

您可以在您的类中放置一个私有方法,该方法使用您想要生成字符串的扩展方法。然后DebuggerDisplay 属性可以引用该方法。

【讨论】:

  • 这假设您可以修改目标类型。原始问题使用DebuggerDisplayAttributeTargetType 属性,所以我认为这里不是这种情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
相关资源
最近更新 更多