【问题标题】:How to handle nameof(this) to report class name如何处理 nameof(this) 以报告类名
【发布时间】:2015-01-08 10:26:56
【问题描述】:

我想使用以下 C#6 代码

var joe = new Self();
Console.WriteLine(joe);

... 并得到以下输出:

下面的尝试

class Self {
  public string Name { get; set; } = nameof(this);
  public override string ToString() {
    return Name;
  }
}

失败,因为 nameof 不能应用于 this。这个问题有解决办法吗?

编辑。我正在使用的场景确保没有两个引用指向同一个 Self 对象。

【问题讨论】:

  • 我不这么认为。考虑var joe = new Self(); var jack = joe;Name 应该返回 "joe""jack",还是两者都返回?
  • nameof(joe) 有什么问题
  • 您可以从这篇文章中了解nameof(..)的一些用法:spicelogic.com/Journal/C-sharp-6-most-exciting-features-9
  • 同一类的不同实例的唯一性是通过ReferenceEqualsEqualsGetHashCode方法实现的,也许可以通过自定义实现(例如Equals可以检查Id字段/property 在两个被检查的实例上)。你用nameof来实现这样一个目标的想法很奇怪……
  • 为什么我们不能使用this.GetType().Name

标签: c# c#-6.0 nameof


【解决方案1】:

不,nameof 旨在引用您所指成员的编译时名称。如果您希望一个对象将 Name 属性作为其状态的一部分,那么这与您 获取Name 属性的方式无关 - 正如 Frédéric Hamidi 所说,可能有多个变量 (或无)指的是同一个对象。基本上,您需要区分对象和恰好引用该对象的变量。

但是,如果您有一个构造函数来指定名称,那么您可以使用一些技巧来更容易获得正确的名称:

class Self
{
    public string Name { get; }

    public Self([CallerMemberName] string name = null)
    {
        this.Name = name;
    }
}

然后:

class Foo
{
    private Self me = new Self(); // Equivalent to new Self("me")

    public void SomeMethod()
    {
        // Can't use the default here, as it would be "SomeMethod".
        // But we can use nameof...
        var joe = new Self(nameof(joe));
    }
}

【讨论】:

    【解决方案2】:

    也许你可以使用以下方法:

        class Self
        {
           public override string ToString()
           {
                return this.GetType().Name;
           }
        }
    

    【讨论】:

      【解决方案3】:

      您可以简单地在变量本身上使用nameof

      Console.WriteLine(nameof(joe));
      

      Here 是一个使用当前 Roslyn 版本的工作示例

      【讨论】:

        【解决方案4】:

        nameof 的想法是使事物类型安全,以便在运行时指定程序元素,但通过编译时类型安全检查。

        应该原子化想要显示的内容。例如,在我的错误消息中,我包含了类名和方法本身的相关信息并对其进行了检查,因此如果我更改任何名称,它们将被捕获为编译时错误:

        class Operation
        {
          public void Execute()
          { 
            try { ... }
            catch (Exception ex)
            {
            Console.Writeline($"{nameof(Operation)}.{nameof(Execute)} has encountered exception:{Environment.NewLine}{Environment.NewLine}{ex.Message}" );
            }
           }
        }
        

        输出

        Operation.Excecute has exception:
        ...
        

        话虽如此,您应该覆盖 ToString() 并报告类名

        public override string ToString() { return nameof(Self); } 
        

        【讨论】:

          【解决方案5】:

          在处理长类名时,我通常会为它创建一个内部常量:

          private const string SomeConst = nameof(Self);
          

          然后你可以在你的代码中使用它:

          Console.WriteLine(SomeConst);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-04-02
            • 2012-07-18
            相关资源
            最近更新 更多