我多次对此表单的烦恼感到磕磕绊绊,所以我的问题是:代码方案的最佳模式/实践如下所示?
这是我最近写的方法体的一个例子:
public HashSet<char> SomeCharacters(IEnumerable<string> _hashes){
HashSet<char> Result = new HashSet<char>();
bool _firstpass = true;
foreach (string _hash in _hashes) {
if (_firstpass) {
Result = new HashSet<char>(_hash);
_firstpass = false;
}
else {
// ...
// some code that uses Result
}
}
return Result;
}
这很好用,但令我讨厌的是第一行
HashSet<char> Result = new HashSet<char>();
我本能地喜欢用HashSet<char> Result;
替换。编译器不会让我,因为else
块使用Result
它不会识别为instanciated,虽然我知道它将在else
块执行时。< / p>
上面的方法迫使我两次创建Result
,这有很多原因(性能,代码美学,......)并不好。
请将此问题视为有关此类情况的问题,而不仅仅关注此特定示例。谢谢!
答案 0 :(得分:5)
最初只需将null
分配给变量:
HashSet<char> Result = null;
然后你也可以摆脱_firstpass
变量:
HashSet<char> Result = null;
foreach (string _hash in _hashes) {
if (Result == null) {
Result = new HashSet<char>(_hash);
}
else {
// ...
// some code that uses Result
}
}
如果迭代字符串集合的唯一目的是将字符串的所有字符放在HashSet<char>
中,那么你可以这样做:
var Result = new HashSet<char>(_hashes.SelectMany(s => s));
这里的原则是,有时您可以使用“first pass create and add”逻辑将循环重写为更简单的LINQ语句,在这些语句中构建序列,然后使用ToList
创建最终对象,或者在本例中为{ {1}}构造函数。
答案 1 :(得分:1)
你可以重构删除标志:
public HashSet<char> SomeCharacters(IEnumerable<string> _hashes){
string first = _hashes.FirstOrDefault();
if(first == null) return new HashSet<char>();
HashSet<char> Result = new HashSet<char>(first);
foreach (string _hash in _hashes.Skip(1)) {
// ...
// some code that uses Result
}
return Result;
}
您需要确保不止一次枚举_hashes
是安全的。