20

我想使用以下 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对象。

4

5 回答 5

18

不,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));
    }
}
于 2015-01-08T10:33:57.893 回答
7

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

    class Self
    {
       public override string ToString()
       {
            return this.GetType().Name;
       }
    }
于 2018-06-09T04:13:35.280 回答
6

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

Console.WriteLine(nameof(joe));

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

于 2015-01-08T10:33:25.043 回答
0

的想法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); } 
于 2016-01-10T18:43:20.427 回答
0

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

private const string SomeConst = nameof(Self);

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

Console.WriteLine(SomeConst);
于 2018-03-15T12:16:45.657 回答