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

时间:2013-04-12 16:12:59

标签: c# enums

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枚举?使用语句是否有某种方法可以做到这一点?

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

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

5 个答案:

答案 0 :(得分:2)

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

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();
        }
    }
}

答案 1 :(得分:2)

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

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

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

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

C# 设计用于在声明的东西是本地时处理颜色问题。 重命名您的本地

答案 2 :(得分:2)

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

// 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 alias directive指向该类型来解决它。然后,您将不必一遍又一遍地重复完整的命名空间。它看起来像这样:

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;
    }
  }
}

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

答案 3 :(得分:1)

使用约定来命名局部变量sameName会更好,原因就像这样。这是一个完整的例子:

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

您说您无法重命名该字段,但您的示例显示了本地变量。这是一个惯例,字段应该只是私有的,不要以大写字母开头。局部变量和私有字段可以,例外情况(例如反射......如果您反映私有字段,则还有其他问题),请始终重命名以满足您的需要。

简而言之,使用好的做法,你就不会遇到这个问题。

答案 4 :(得分:0)

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

QUIZ:此代码输出是什么(假设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; }