这里和这里有一些相关的问题,但它们并没有真正给我满意的答案.问题是嵌套在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; }
...
}
Run Code Online (Sandbox Code Playgroud)
有一些选项可以解决这个问题,但它们对我来说似乎并不合适.
我可以在课堂外移动枚举,但是你只会说Suit而不是Card.Suit,这对我来说似乎不对.什么是Suit外界的背景Card?
我可以移动它们的类外,并将其更改为类似CardSuit和CardRank,但后来我觉得我在烤的上下文信息到枚举时,应该由一个类或命名空间名称进行处理的名称.
我可以改变枚举到的名字Suits和Ranks,但是这违反了微软的命名规则.它感觉不对劲.
我可以更改属性名称.但到了什么?我觉得直觉对我来说是对的Suit = Card.Suit.Spades.
我可以将枚举移动到一个单独的静态类中,该类CardInfo只包含这些枚举.如果我不能提出任何其他建议,我认为这是最好的选择.
所以我想知道其他人在类似的情况下做了什么.知道为什么不允许这样做也很好.也许埃里克·利珀特(Eric Lippert)或其他人可能会决定禁止它?它似乎只会在类中产生歧义,这可以通过强制使用this.Suit …
我正在考虑一个符合一套合同的集合,但我认为这个问题适用于任何类型..NET框架中是否存在阻止空条目的集合?我想要的具体行为是这样的:
var set = new HashSet<object>();
bool added = set.Add(null);
Console.WriteLine(added); // prints "False"
Run Code Online (Sandbox Code Playgroud)
这不是内置的行为HashSet<T>.是否存在任何具有此(或类似)行为的集合,或者我最好自己滚动?如果是后者,最好的方法是什么?我应该直接继承HashSet<T>还是仅包装?
编辑:要清楚,这只是空闲的想知道.主要是因为我想不出任何理由,我会永远想允许null进入一组对象.我对此没有任何特别需要.
.NET Framework正在添加ISet<T>4.0版本的接口.在同一版本中,F#被添加为一流语言.F#提供了一个不可变的Set<'T>类.
对我来说,提供的不可变集合将实现ISet<T>接口似乎是合乎逻辑的,但事实并非如此.有谁知道为什么?
我的猜测是他们不想实现一个可变的接口,但我认为这种解释并不成立.毕竟,他们的Map<'Key, 'Value>类实现IDictionary,这是可变的.并且在实现仅部分适当的接口的类的框架中的其他地方存在示例.
我的另一个想法是ISet<T>新的,所以也许他们没有解决它.但这似乎有点薄.
ISet<T>通用(v.IDictionary,不是)的事实是否与它有关?
对此事的任何想法将不胜感激.
我正在考虑通用类HashSet<T>.它实现了几个接口,但没有公开一个集合的正确语义.具体来说,没有人支持Add返回的方法bool.(ICollection<T>支持void Add,可以在夹点中使用.)这些接口也不支持常见的设置操作,如联合和交叉.(虽然必须说这些操作中的一些可以通过扩展来获得IEnumerable<T>.)
这意味着该类只能像直接实现的集合一样使用.即,你不能做这样的事情:
ISet<int> = new HashSet<int>;
Run Code Online (Sandbox Code Playgroud)
不管怎么说,据我所知.那么是什么促使人们选择这样做呢?
也许最重要的是:即使你可以投射HashSet<T>到ICollection<T>等人,你也会在你暴露的API中失去语义价值.也就是说,您的API的消费者没有迹象表明他们正在使用一套.因此,当你可以打电话ICollection<T>.Add过来时,如果他们试图两次添加一个项目并且它不起作用,人们就会感到困惑.设置界面会给人们正确的期望.