Có - sử dụng Dictionary.TryGetValue
. Phải có tham số out
để nhận giá trị và trả về giá trị được tìm thấy hay không. Đây là mã điều chỉnh của bạn:
foreach(var item in newInfo)
{
int value;
if (myDict.TryGetValue(item.Name, out value))
{
myDict[item.Name] = value + item.NewInfo;
}
else
{
myDict[item.Name] = item.NewInfo;
}
}
Tuy nhiên, chúng ta có thể làm tốt hơn rằng trong trường hợp đặc biệt này. Nếu phím-không phải là được tìm thấy, thông số out
được đặt thành 0. Khi chúng tôi sẽ đặt giá trị mới thành item.NewInfo
hoặc item.NewInfo + value
, chúng tôi cũng thực sự làm điều tương tự. Chúng ta có thể bỏ qua các giá trị trả về của phương pháp này, và chỉ sử dụng:
foreach(var item in newInfo)
{
int value;
myDict.TryGetValue(item.Name, out value);
myDict[item.Name] = value + item.NewInfo;
}
Đó là khá bất thường mặc dù - thường bạn sẽ sử dụng giá trị trả về, rõ ràng.
digression
Đó là chỉ vì bạn đang thực sự làm một hoạt động GetValueOrDefault
rằng nó hoạt động. Trong thực tế, đó sẽ là một cặp giá trị của phương pháp khuyến nông:
public static TValue GetValueOrDefault<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary, TKey key)
{
TValue value;
dictionary.TryGetValue(key, out value);
return value;
}
public static TValue GetValueOrDefault<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary, TKey key,
TValue customDefault)
{
TValue value;
if (dictionary.TryGetValue(key, out value))
{
return value;
}
else
{
return customDefault;
}
}
Tại thời điểm mà bạn có thể làm cho mã của bạn rõ ràng và ngắn gọn:
foreach(var item in newInfo)
{
myDict[item.Name] = myDict.GetValueOrDefault(item.Name) + item.NewInfo;
}
(Bạn có thể gọi GetValueOrDefault(item.Name, 0)
cho rõ ràng có khả năng hơn .)
Quay lại điểm ...
Lưu ý rằng bạn vẫn đang thực hiện hai lần tra cứu - một để tìm giá trị và một để thêm/thay thế nó. Bạn thực sự không thể tránh điều đó mà không làm cho đối số loại TValue
có thể thay đổi, mà bạn có thể thay đổi tại chỗ. Điều đó sẽ có thể, nhưng không phải là tuyệt vời.
Trong mã ban đầu, bạn có khả năng thực hiện ba tìm kiếm - một cho ContainsKey
và sau đó hai (nếu tìm thấy khóa) để thay thế giá trị. Nó dễ dàng hơn để thấy rằng nếu chúng ta mở rộng +=
:
myDict[item.Name] = myDict[item.Name] + item.NewInfo;
(. item.Name
sẽ chỉ được đánh giá một lần, nhưng khác hơn là nó giống nhau)
digression Một
Sẽ tốt để có một hoạt động trên Dictionary
đã thực hiện "tra cứu và thay thế" dựa trên một hàm để lấy giá trị mới dựa trên giá trị cũ, ví dụ:
bool Update(TKey key, Func<TValue, bool, TValue> replacementFunction)
nơi replacementFunction
sẽ là một hàm lấy giá trị hiện tại (hoặc giá trị mặc định của TValue
nếu phím không được tìm thấy) và một Boolean để nói hay không phím được thực sự tìm thấy, và lợi nhuận giá trị mới. Từ điển có thể tra cứu khóa, gọi hàm thay thế và cập nhật giá trị tại chỗ. (Không thể triển khai phương thức này dưới dạng phương thức mở rộng.)
Trong khi chức năng này, chỉ cần biết rằng giá trị chỉ bằng 0 vì giá trị mặc định cho loại int là 0. Từ góc độ mã hóa phòng thủ, khả năng đọc này (và khả năng bảo trì) cho tính ngắn gọn. Tôi muốn gắn bó với những gì bạn có, thành thật mà nói. –
Tôi sẽ đưa ra cảnh báo lớn hơn - chắc chắn đó là trường hợp đặc biệt. –
Bạn vẫn không băm mỗi mục hai lần? Một lần trong TryGetValue, và một lần nữa, nơi bạn nói 'myDict [item.Name]'? –