4

关于 Enum VS 属性名称冲突的问题有thisthisthis 。

我的问题不是关于命名约定,而是我想知道如何解决下面代码中演示的名称冲突:

namespace Test
{
    public class Person
    {
        // 1)
        // Gender? Gender { get; set; }

        // 2)
        Gender Gender { get; set; }

        public Person ()
        {
            // 1 - Error CS1061: Type `Test.Gender?' does not contain a definition for `Male' and no extension method `Male' of type `Test.Gender?' could be found (are you missing a using directive or an assembly reference?) (CS1061) (Test)
            // 2 - OK
            Gender = Gender.Male;
        }
    }

    public enum Gender
    {
        Male = 1,
        Female
    }
}

如果我在 2) 中声明属性,Gender Gender { get; set; }则代码编译成功,但是,如果我在 1) 中声明Gender? Gender { get; set; }(在上面的代码中注释)我得到错误

Error CS1061: Type `Test.Gender?' does not contain a definition for `Male' and no extension method `Male' of type `Test.Gender?' could be found (are you missing a using directive or an assembly reference?) (CS1061) (Test)

为什么会这样?

4

2 回答 2

7

Gender?意思是Nullable<Gender>,这意味着当您编写Gender.Male编译器时,编译器认为您正试图MaleNullable<Gender>实例上调用的属性上调用 getter,即被Gender解释为对this.Gender属性的读取以及对结果Male调用的属性的读取。Male

编译器不会将 case (2) 识别为错误,因为枚举不能有方法,因此唯一有意义的解决方案是符号本身是枚举本身。

您可以通过增加名称限定来解决此问题:

namespace Acme.Fruits.Banana
{
    ...
    public Person()
    {
        Gender = Banana.Gender.Male
    }
    ...
}
于 2013-01-17T18:58:14.737 回答
2

属性或局部变量优先于类型/枚举,这意味着如果声明与类型/枚举同名的变量或属性,编译器会将标识符的任何使用解析为变量/属性。

public class Test
{
     public static void SomeMethod(){}
}

public static void Main()
{
     Test.SomeMethod();//ERROR... cannot use variable before declaring it.
     object Test = new object();
     Test.SomeMethod();//ERROR... object does not have a method SomeMethod
}

此规则的唯一例外是如果属性/变量与其自己的类型具有相同的名称,在这种情况下编译器允许它访问静态成员。

public class Test
{
     public static void SomeMethod(){}
}

public static void Main()
{         
     Test Test = new Test();
     Test.SomeMethod();//Works
}

然而,可为空的类型与它所包含的类型不同,而是名称的形式为Nullable<T>,并且两者之间只有隐式转换,因此在可为空的情况下,编译器将不再允许访问枚举成员或静态属性。

public struct Test
{
     public static void SomeMethod(){}
}

public static void Main()
{         
     Test? Test = new Test();
     Test.SomeMethod();//ERROR... Test does not have method SomeMethod
}

以类似的方式,它必须是变量的类型化声明,因为编译器需要关于它,例如以下内容将不起作用:

public class Test
{
     public static void SomeMethod(){}
}

public static void Main()
{         
     object Test = new Test();
     Test.SomeMethod();////ERROR... object does not have a instance method SomeMethod
}
于 2017-05-16T18:46:06.873 回答