如何将 DebuggerDisplay 属性应用于 Enum?

问题描述 投票:0回答:1

问题:我想使用字符串类型的Enum。
我有一个扩展方法,它根据我的枚举返回字符串值。而且,该扩展还支持注册来自数据库或作为 Web API 输入的新值。
因此,枚举的用例是具有预定义的常量,我可以在代码中针对特定情况使用这些常量。

完整示例请参见:https://dotnetfiddle.net/BFkkd7

var pdf = FileExtensionEnum.PDF;
Console.WriteLine(pdf);                         //Output: "PDF"
Console.WriteLine(pdf.ToExtensionString());     //Output: ".pdf"

var newExtension = (FileExtensionEnum)10;
Console.WriteLine(newExtension);                         //Output: 10
Console.WriteLine(newExtension.ToExtensionString());     //Output: "10"
            
var registeredFile = ".png".FromStringExtension();
Console.WriteLine(registeredFile);                         //Output: 4
Console.WriteLine(registeredFile.ToExtensionString());     //Output: ".png"

但是,在调试器中它看起来像这样:

newExtension 变量保存值“10”,并将显示为 10,因为它是 FileExtensionEnum 的未知值,并且对于我的扩展方法来说也是未知值。
registeredFile 值对于 FileExtensionEnum 未知,将显示为 4,但我的扩展程序会将其显示为 ".png"

剩下的部分是使用我的扩展方法强制调试器显示FileExtensionEnum。因此,它将始终显示为字符串。
下面是我尝试为 Visual Studio 2022 做的事情。

想法 1 - 重写 ToString()
但对于 Enum 类型来说这是不可能的。

想法 2 - 调试器显示属性
我尝试以多种方式使用 DebuggerDisplayAttribute。
这些行中的任何一行都给出相同的结果:
[DebuggerDisplay("Value = {this.ToExtensionString()}")]
[DebuggerDisplay("Value = {EnumToString.EnumStringExtension.ToExtensionString(this)}")]
[DebuggerDisplay("Value = {this}")]
[DebuggerDisplay("Value = {GetValue()}")]

[assembly: DebuggerDisplay("Value = {EnumToString.EnumStringExtension.ToExtensionString(this)}", Target = typeof(EnumToString.FileExtensionEnum))]

// result
pdf Value = <Internal Error evaluating expression>  EnumToString.FileExtensionEnum

想法 3 - DebuggerTypeProxyAttribute
public class EnumStringDebugView
{
    private readonly FileExtensionEnum value;
    public EnumStringDebugView(FileExtensionEnum value) => this.value = value;
    public override string ToString() => value.ToExtensionString();
}

// Compilation time error:
// CS0592   Attribute 'DebuggerTypeProxy' is not valid on this declaration type. It is only valid on 'assembly, class, struct' declarations.
[DebuggerTypeProxy(typeof(EnumStringDebugView))]
public enum FileExtensionEnum

// Does not fail, but just ignored
[assembly: DebuggerTypeProxy(typeof(EnumToString.EnumStringDebugView), Target = typeof(EnumToString.FileExtensionEnum))]
想法 4 - 使用带有静态只读字符串的自定义类
是的,我可以使用静态只读字段定义自己的类。但是,不可能将其用作可选参数的默认值。使用 Enum - 你可以。
public class SampleStringCode
{
    private string readonly _value;
    private SampleStringCode(string value) => this._value = value;

    public static readonly SampleStringCode S1 = new("S1");
    public static readonly SampleStringCode S2 = new("S2");
    public static readonly SampleStringCode S3 = new("S3");
}
想法 5 - 字符串常量
是的,我们可以简单地使用字符串常量,这是我当前的解决方案。
但是,作为一名新开发人员 - 我不知道我们在哪里有可以用于该特定属性的常量。
枚举和自定义类解决了这个问题,但也存在其他问题。
想法 6 - 自定义代码分析器
如果我们有一个带有字符串常量的类:
public static class FileExtenions
{
    public const string EXCEL = ".excel";
    public const string PDF = ".pdf";
    public const string JPG = ".jpg";
}

然后我们可以拥有一个可以应用于字符串属性或字符串参数的自定义属性。

public class Document
{
    [UseConst(typeof(FileExtenions))]
    public string Extension { get; set; }
}

然后实现一个自定义代码分析器,它基于属性限制您将任何字符串分配给属性,除了来自 FileExtenions 类的常量。
我并没有尝试这样做,但听起来有点矫枉过正。但就代码简单性而言,这将是最好的。无需编写额外的代码,无需编写自定义 EF 转换器或 JSON 转换器或 API 的 ModelBinding。但你必须使用自定义属性。


那么,如何在 VisualStudio 2022 中将 DebuggerDisplayAttribute 应用于 Enum
c# enums
1个回答
0
投票

在枚举的编译版本中,私有字段“value__”保存数值。您可以使用它来显示数值,如下所示:

[DebuggerDisplay("Value: {value__}")]
enum Foo { Bar = -1, Baz=1 }

或者简单地

[DebuggerDisplay("{value__}")]
enum Foo { Bar = -1, Baz=1 }

在 vs2019 和 vs2022 的各种框架上进行了测试

© www.soinside.com 2019 - 2024. All rights reserved.