c# Enum与Nullable属性名称冲突



关于Enum和Property名称冲突的问题有this, this和this。

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

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)

Gender?意味着Nullable<Gender>,这意味着当你写Gender.Male时,编译器认为你试图在Nullable<Gender>实例上调用一个名为Male的属性的getter,即Gender被解释为对this.Gender属性的读取,Male被解释为对Male属性的读取。

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

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

namespace Acme.Fruits.Banana
{
    ...
    public Person()
    {
        Gender = Banana.Gender.Male
    }
    ...
}

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

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
}

相关内容

  • 没有找到相关文章

最新更新