关于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
}