代码之家  ›  专栏  ›  技术社区  ›  Sean Devlin

嵌套枚举和属性命名冲突

  •  27
  • Sean Devlin  · 技术社区  · 15 年前

    有一些相关的问题 here here 但是他们没有给我满意的答案。问题是嵌套在C中的类中的枚举不能与该类的属性同名。我的例子:

    public class Card
    {
        public enum Suit
        {
            Clubs,
            Diamonds,
            Spades,
            Hearts
        }
    
        public enum Rank
        {
            Two,
            Three,
            ...
            King,
            Ace
        }
    
        public Suit Suit { get; private set; }
        public Rank Rank { get; private set; }
        ...
    }
    

    有几种方法可以解决这个问题,但我觉得它们不太合适。

    我可以把枚举移到教室外面,但你会说 Suit 而不是 Card.Suit 这对我来说似乎是错误的。什么是 西服 Card 是吗?

    我可以把他们搬出教室,换成 CardSuit CardRank ,但我会觉得我正在将上下文信息烘焙到枚举的名称中,而这个名称应该由类或命名空间名称处理。

    我可以把枚举的名称改为 Suits Ranks ,但这违反了 Microsoft's naming guidelines .只是感觉不对劲。

    我可以更改物业名称。但是为了什么呢?我凭直觉认为我想说的是对的 Suit = Card.Suit.Spades .

    我可以将枚举移动到一个单独的静态类 CardInfo 只包含这些枚举。如果我不能想出别的办法,我认为这是最好的选择。

    所以我想知道其他人在类似的情况下做了什么。很高兴知道为什么不允许这样做。也许埃里克·利珀特或是有人会插嘴阻止它的决定?似乎它只会造成歧义 在内部 类,这可以通过强制使用 this.Suit 属性名。(类似于消除当地人和成员之间的歧义)我认为这是由于 "every feature starts with -100 points" 但我对围绕这件事的讨论很好奇。

    7 回复  |  直到 7 年前
        2
  •  3
  •   Victor Hurdugaci    15 年前

    SuitOptions
    RankOptions
    

    myCard.Suit = Card.SuitOptions.Clubs;
    

        3
  •  3
  •   Gordon Gustafson    15 年前

    if (card.CardSuit == Card.Suit.Ace) { }  //need different name for Suit field
    

    if (card.Suit == Suit.Ace) { } //no naming clashes, easier to read
    
        4
  •  1
  •   Kevin Kibler    15 年前

        5
  •  1
  •   Ray    15 年前

        6
  •  1
  •   comecme    13 年前

    Microsoft Naming Guidelines the code sample for the enum keyword

    enum Days { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
    
        7
  •  0
  •   samus    7 年前

    enum struct int Value

    public class Record
    {
        public enum DurationUnit { Minutes, Hours }
    
        public struct DurationStruct
        {
            public readonly int Value;
            public readonly DurationUnit Unit;
    
            public DurationStruct(int value, DurationUnit unit)
            {
                Value = value;
                Unit = unit;
            }
        }
        public DurationStruct Duration; //{get; set;} -can't return a ref to a val type (in C#)
    
        public void Init()
        {   
            // initialize struct (not really "new" like a ref type)
            // -helpful syntax if DurationStruct ever graduated/ascended to class
            Duration = new DurationStruct(1, DurationUnit.Hours);
        }
    }    
    

    Card

    public class Card
    {
        public enum Suit { Clubs, Diamonds, Spades, Hearts }
        public enum Rank { Two, Three, ...  King, Ace }
    
        public struct CardStruct
        {
            public Card.Suit Suit { get; private set; }
            public Card.Rank Rank { get; private set; }
        }
    
        //public CardStruct Card {get; set;} -can't be same as enclosing class either
        public CardStruct Identity {get; set;}
    
        public int Value
        {
            get    
            {
                //switch((Suit)Card.Suit)
                switch((Suit)Identity.Suit)
                {
                    //case Suit.Hearts:   return Card.Rank + 0*14;
                    case Suit.Hearts:   return Identity.Rank + 0*14;
                    case Suit.Clubs:    return Identity.Rank + 1*14;
                    case Suit.Diamonds: return Identity.Rank + 2*14;
                    case Suit.Spades:   return Identity.Rank + 3*14;                
                }
            }
        }
    }