如何在不指定命名空间的情况下消除字段的枚举歧义

本文关键字:情况下 字段 歧义 枚举 命名空间 | 更新日期: 2023-09-27 18:08:46

enum SameName { Value }
class Tester
{
   void Method1() {
      SameName SameName;
      SameName test = SameName.Value;
   }
   void Method2() {
      string SameName;
      SameName test = SameName.Value;
   }
}

在第一种方法中,编译器正确地推断出 SameName.Value 引用枚举。

在第二种方法中,编译器感到困惑,并认为 SameName.Value 引用的是字符串类的 Value 成员。由于不存在这样的成员,因此会出错。

在这种情况下,我可以做些什么来帮助编译器更了解我的 SameName 枚举?有没有办法使用语句来做到这一点?

  • 我无法在我的真实代码中重命名变量或枚举。
  • 正在创建一个包含许多枚举值的大型字典,我宁愿不在枚举的每个实例前面添加命名空间前缀。

更新:是的,我知道我不应该使用大写的局部变量。是的,我意识到这些是局部变量,而不是字段。是的,我意识到如果真正的代码看起来像这样,调试起来会很糟糕。我把上面写成一个简短的、人为的例子,展示了我在实际代码中遇到的问题。我很抱歉我没有明确表达我的意图。在实际代码中,类位于枚举命名空间中包含的命名空间中,局部变量是基类中的属性。我试图删除所有无关的代码以使问题更容易发现,并列出了我的要求,以便为问题提供一点范围。

如何在不指定命名空间的情况下消除字段的枚举歧义

好的,根据您的更新,我认为我们可以为您提供帮助。现在的情况更有意义了。我想有代码:

// in a place you're not allowed to edit
namespace Outer
{
  public enum SameName { Value, }
}

// in a place you're not allowed to edit
namespace BaseSpace
{
  public class TesterBase
  {
    public string SameName { get; set; }
  }
}

然后您在可以编辑的第三个代码文件中遇到了问题。我建议你用指向类型的using别名指令来解决它。这样,您就不必一遍又一遍地重复完整的命名空间。它将看起来像这样:

using BaseSpace;
using snEnum = Outer.SameName;          // this helps you (a using alias)
namespace Outer.Inner
{
  public class Tester : TesterBase
  {
    void Method2() {
      snEnum test = snEnum.Value;
    }
  }
}

请注意,使用 alias 指令可以"指向"命名空间或类型(如本例所示(。他们为您提供了一个您经常使用的繁琐名称的简写。

您可以为枚举类型使用别名

namespace ConsoleApplication13
{
    using NewEnumName = ConsoleApplication13.SameName;
    internal enum SameName { Value }
    internal class Tester
    {
        private void Method1()
        {
            SameName SameName;
            SameName test = SameName.Value;
        }
        private void Method2()
        {
            string SameName;
            SameName test = NewEnumName.Value;
        }
    }
    public class Program
    {
        private static void Main(string[] args)
        {
            Console.ReadKey();
        }
    }
}

C# 被设计为在面对与其类型相同的属性时变得健壮,因为这很常见:

class Shape
{
    public Color Color { get; set; }
    ...

如果你有一个颜色类型,那么有一个也称为 Color 的属性是很常见的,并且没有很好的方法来重命名它们中的任何一个。 因此,C# 旨在合理优雅地处理这种情况。 请参阅我 2009 年的文章,了解有关颜色问题的一些有趣细节:

http://blogs.msdn.com/b/ericlippert/archive/2009/07/06/color-color.aspx

C# 不是为在声明的事物是本地事物时处理颜色颜色问题而设计的。重命名本地

出于

这样的原因,最好使用约定来命名局部变量sameName。 下面是一个完整的示例:

enum SameName { Value }
class Tester
{
   void Method1() {
      SameName sameName;
      SameName test = SameName.Value;
   }
   void Method2() {
      string sameName;
      SameName test = SameName.Value;
   }
}

您说无法重命名字段,但您的示例显示了局部变量。 按照惯例,字段只能是私有的,不要以大写字母开头。 局部变量和私有字段可以,但极少数例外(例如反射...如果你正在反映私有领域,你还有其他问题(,总是重命名以适应你需要的任何内容。

简而言之,使用良好做法,您就不会遇到此问题。

这不是一个真正的答案。而是受以下问题启发的观察:

测验:这段代码输出什么(假设System.Object实例方法ToString()GetHashCode()(?

class Color
{
  private static new int ToString()
  { return 42; }
  public static new string GetHashCode()
  { return "I'm public!"; }
}
static class Program
{
  static void Main()
  {
    Color Color = new Color();
    var testA = Color.ToString();
    var testB = Color.GetHashCode();
    Console.WriteLine(testA);
    Console.WriteLine(testB);
  }
}

答:由于Color定义了与其继承的实例方法具有相同名称和签名的新静态方法,因此编译器可以选择两个重载。在ToString的情况下,它选择实例方法,这很幸运,因为静态方法是私有的。但是对于GetHashCode,它选择了静态方法。颜色-颜色魔法。

补充说明:对于那些反对用大写首字母命名局部变量的人,当 Color-Color 是直接类成员时,可以做同样的例子,例如 public static Color Color { get; set; } .

相关文章: