【问题标题】:C# Enum VS Nullable Property name conflictC# Enum VS Nullable 属性名称冲突
【发布时间】:2013-01-17 18:54:17
【问题描述】:

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)

为什么会这样?

【问题讨论】:

    标签: c# .net enums nullable naming


    【解决方案1】:

    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
        }
        ...
    }
    

    【讨论】:

    • @Bobson:我进行了编辑以展示如何解决此问题。调整到您正在使用的命名空间。
    【解决方案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
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-07
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 2021-08-14
      • 1970-01-01
      相关资源
      最近更新 更多