0
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 枚举?有没有办法用 using 语句来做到这一点?

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

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

4

5 回答 5

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# 的设计目的不是处理颜色颜色问题。重命名您的本地.

于 2013-04-12T16:30:44.200 回答
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();
        }
    }
}
于 2013-04-12T16:16:47.653 回答
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别名指令来解决它。这样您就不必一遍又一遍地重复完整的命名空间。它看起来像这样:

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

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

于 2013-04-12T18:01:51.770 回答
1

sameName出于诸如此类的原因,使用命名局部变量的约定会好得多。这是一个完整的例子:

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

您说您无法重命名该字段,但您的示例显示了局部变量。这是一个约定,字段只能是私有的,并且不能以大写字母开头。局部变量和私有字段可以,除了极少数例外(例如反射......如果你正在反射私有字段,你还有其他问题),总是可以重命名以适应你需要的任何东西。

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

于 2013-04-12T16:25:44.367 回答
0

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

测验:这段代码输出了什么(假设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; }

于 2013-04-12T17:19:58.073 回答