C#Enum VS Nullable属性名称冲突

时间:2013-01-17 18:54:18

标签: c# .net enums nullable naming

有关于Enum VS Property name冲突的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)

为什么会这样?

2 个答案:

答案 0 :(得分:6)

Gender?表示Nullable<Gender>,这意味着当您编写Gender.Male时,编译器认为您正在尝试在{{1}上调用名为Male的属性上的getter实例,即Nullable<Gender>被解释为Gender属性的读取,this.Gender被解释为读取属性Male的属性。

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

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

Male

答案 1 :(得分:1)

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

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
}