2010-03-17 16 views
0

我有一个ICollection,我知道只会有一个成员。目前,我通过循环,知道循环将只运行一次,以获取价值。有没有更干净的方法来做到这一点?C#:轻松访问单身ICollection <>的成员?

我可以改变persistentState对象来返回单个值,但这会使接口的其余部分复杂化。它从XML中获取数据,并且大部分ICollection是合适的。

// worldMapLinks ensured to be a singleton 
ICollection<IDictionary<string, string>> worldMapLinks = persistentState.GetAllOfType("worldMapLink"); 

string levelName = ""; //worldMapLinks.GetEnumerator().Current['filePath']; 

// this loop will only run once 
foreach (IDictionary<string, string> dict in worldMapLinks) // hacky hack hack hack 
{ 
    levelName = dict["filePath"]; 
} 

// proceed with levelName 
loadLevel(levelName); 

这里是同一个问题的另一个例子:

// meta will be a singleton 
ICollection<IDictionary<string, string>> meta = persistentState.GetAllOfType("meta"); 
foreach (IDictionary<string, string> dict in meta) // this loop should only run once. HACKS. 
{ 
    currentLevelName = dict["name"]; 
    currentLevelCaption = dict["teaserCaption"]; 
} 

另一个例子:

private Vector2 startPositionOfKV(ICollection<IDictionary<string, string>> dicts) 
{ 
    Vector2 result = new Vector2(); 
    foreach (IDictionary<string, string> dict in dicts) // this loop will only ever run once 
    { 
     result.X = Single.Parse(dict["x"]); 
     result.Y = Single.Parse(dict["y"]); 
    } 

    return result; 
} 

回答

4

为什么不使用单个或FirstOrDefault扩展方法?

var levelName = worldMapLinks.Single().Value; 

单一的优点是强制假设枚举中只有一个值。如果这不是真的,会引发异常,迫使你重新考虑你的逻辑。如果枚举中没有至少一个元素,则FirstOrDefault将返回一个默认值。

+0

+1更好的答案 - 'Single'是这里的最佳选择。 :) – 2010-03-17 18:17:27

0

如果你可以在你的类中使用LINQ-to-objects,如果你知道只有一个成员,那么在集合上使用Single()扩展方法。否则,如果可能有零个或一个,请使用SingleOrDefault()

0

为什么你只有一个成员的集合?看来真正的答案应该是更好地设计你的系统,而不是依靠任何方法从集合中检索一个元素。你说这使得它更复杂,但是如何?这个解决方案本身不是一个并发症吗?是否有可能将接口更改为在适用的情况下返回一个元素,并在其他位置收集集合?看起来像一个代码味道给我。

+0

这绝对是可能的,但现在使用@ JaredPar的答案似乎更好。 – 2010-03-17 20:27:45

+0

我同意。看起来如果有一种情况,当你知道你只会接收到一个元素时,这暗示有更好的语义选项。可能还有其他情况下会返回大量集合,但我认为不同的方法适用于这些集合。 – 2010-03-17 22:48:11

相关问题