Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在不指定名称空间的情况下消除枚举与字段之间的歧义?_C#_Enums - Fatal编程技术网

C# 如何在不指定名称空间的情况下消除枚举与字段之间的歧义?

C# 如何在不指定名称空间的情况下消除枚举与字段之间的歧义?,c#,enums,C#,Enums,在第一个方法中,编译器正确地判断SameName.Value引用的是枚举 在第二个方法中,编译器会感到困惑,认为samenae.Value引用的是string类的Value成员。由于不存在这样的成员,因此会出现错误 在此上下文中,我可以做些什么来帮助编译器更好地了解我的SameName枚举?使用语句有什么方法可以做到这一点吗 我无法在实际代码中重命名变量或枚举。 我正在创建一个包含许多枚举值的大型字典,我不希望在枚举的每个实例前面添加名称空间前缀。 更新:是的,我知道我不应该使用大写的局部变量。

在第一个方法中,编译器正确地判断SameName.Value引用的是枚举

在第二个方法中,编译器会感到困惑,认为samenae.Value引用的是string类的Value成员。由于不存在这样的成员,因此会出现错误

在此上下文中,我可以做些什么来帮助编译器更好地了解我的SameName枚举?使用语句有什么方法可以做到这一点吗

我无法在实际代码中重命名变量或枚举。
我正在创建一个包含许多枚举值的大型字典,我不希望在枚举的每个实例前面添加名称空间前缀。 更新:是的,我知道我不应该使用大写的局部变量。是的,我知道这些是局部变量,不是字段。是的,我意识到如果真正的代码看起来像这样,那么调试起来会很糟糕。我把上面的内容写成了一个简短的、人为的例子,说明了我在实际代码中遇到的问题。很抱歉,我没有说清楚我的意图。在实际代码中,类位于枚举命名空间中包含的命名空间中,局部变量是基类中的属性。我已尝试删除所有无关的代码,以使问题更容易发现,并列出了我的要求,为问题提供了一个小范围。

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

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

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

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被设计为在遇到与其类型相同的属性时具有健壮性,因为这是常见的:

enum SameName { Value }
class Tester
{
   void Method1() {
      SameName sameName;
      SameName test = SameName.Value;
   }
   void Method2() {
      string sameName;
      SameName test = SameName.Value;
   }
}
如果您有一个类型Color,通常会有一个属性也称为Color,并且没有好的方法重命名它们。因此,C被设计成合理优雅地处理这种情况。有关颜色问题的一些有趣细节,请参阅我2009年的文章:


当所声明的对象是本地对象时,C不是用来处理颜色问题的。重命名您的本地帐户。

这不是一个真正的答案。相反,这是一个受到以下问题启发的观察结果:

小测验:给定那个系统,这个代码输出什么。对象有实例方法ToString和GetHashCode

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


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

好的,根据您的更新,我想我们可以帮助您。现在的情况更有道理了。我想有一个代码:

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

然后在第三个可以编辑的代码文件中出现问题。我建议你通过指向类型来解决它。这样您就不必一次又一次地重复完整的名称空间。它将如下所示:

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

请注意,使用别名指令可以指向命名空间或类似于本例中的类型。它们为你提供了一个你经常使用的繁琐名称的简写。

你的示例不使用字段,而是使用违反局部变量命名约定的局部变量。嗯。不要那样做?为什么将局部变量命名为与类型相同的名称?这只会导致混乱。那么,为什么不使用全名呢?这正是对类、枚举、结构等使用名称空间前缀的原因。我不希望在枚举的每个实例前面添加名称空间前缀。不要偷懒,如果你写了这段代码,你就在这里自掘坟墓。我不想在几个月后调试你的代码。为什么不添加名称空间前缀以提高可读性?此外,这将解决这个问题。没有理由不添加名称空间前缀.Upvoted,因为我发现Method1和Method2之间存在差异,这很有趣。我想检查一下C规范中的哪个规则使得这两种情况不相等。即使最初的问题看起来有点愚蠢,为什么方法1是允许的,而方法2是不允许的?这让我感到惊讶。因为在这两种情况下,局部变量与类型具有相同的名称,该类型与当前类型位于相同的命名空间中,但不嵌套在当前类型中。
既然你非常了解C规范,也许你可以马上告诉我这个差异是从哪里来的?测试了一下。如果我们将SameName从枚举更改为类,其中该类有一个名为Value的可访问静态字段,则Method1仍然有效。他们之所以允许这样做而不惹麻烦,似乎是因为很难给SameName两个成员,一个是静态的,一个是非静态的,它们都有相同的名称。另一方面,使用Method2,您可以轻松地为SameName类型提供一个静态成员,其名称与System.String的实例成员之一相同。这将是一个严重的歧义。谢谢你对别名的清晰描述。我能够将这些信息带给我的利益相关者,并解释为什么应该允许我指定名称空间。
// 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 BaseSpace;
using snEnum = Outer.SameName;          // this helps you (a using alias)

namespace Outer.Inner
{
  public class Tester : TesterBase
  {
    void Method2() {
      snEnum test = snEnum.Value;
    }
  }
}