Dictionary.add(key, value)
과 의 차이점은 무엇입니까 Dictionary[key] = value
?
ArgumentException
중복 키를 삽입 할 때 마지막 버전이 던지지 않는다는 것을 알았는데 첫 번째 버전을 선호하는 이유가 있습니까?
편집 : 누구든지 이것에 대한 정보의 권위있는 출처를 가지고 있습니까? 나는 MSDN을 시도했지만 항상 야생 거위 추적입니다 🙁
답변
성능은 거의 100 % 동일합니다. Reflector.net에서 클래스를 열어 확인할 수 있습니다.
This 인덱서입니다.
public TValue this[TKey key]
{
get
{
int index = this.FindEntry(key);
if (index >= 0)
{
return this.entries[index].value;
}
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
this.Insert(key, value, false);
}
}
그리고 이것은 Add 메서드입니다.
public void Add(TKey key, TValue value)
{
this.Insert(key, value, true);
}
다소 길기 때문에 전체 Insert 메서드를 게시하지는 않지만 메서드 선언은 다음과 같습니다.
private void Insert(TKey key, TValue value, bool add)
함수에서 더 아래로 내려 가면 다음과 같은 일이 발생합니다.
if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key))
{
if (add)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
키가 이미 존재하는지 확인하고 존재하고 매개 변수 add가 true이면 예외를 발생시킵니다.
따라서 모든 목적과 의도에 대해 성능은 동일합니다.
다른 몇 가지 언급과 마찬가지로 동일한 키를 두 번 추가하려는 시도에 대해 확인이 필요한지 여부에 관한 것입니다.
긴 게시물에 대해 죄송합니다. 괜찮기를 바랍니다.
답변
첫 번째 버전은 새 KeyValuePair를 사전에 추가하여 키가 이미 사전에 있으면 던집니다. 두 번째는 인덱서를 사용하여 키가없는 경우 새 쌍을 추가하지만 사전에 이미있는 경우 키 값을 덮어 씁니다.
IDictionary<string, string> strings = new Dictionary<string, string>();
strings["foo"] = "bar"; //strings["foo"] == "bar"
strings["foo"] = string.Empty; //strings["foo"] == string.empty
strings.Add("foo", "bar"); //throws
답변
Dictionary.Add(key, value)
및 Dictionary[key] = value
다른 목적을 가지고 :
- 이
Add
메서드를 사용하여 새 키 / 값 쌍 을 추가 하면 기존 키가 대체되지 않습니다 (ArgumentException
가 발생 함). - 키가 사전에 이미 있는지 여부를 신경 쓰지 않는 경우 인덱서를 사용합니다. 즉, 키가 사전에 없으면 키 / 값 쌍을 추가하고 키가 이미 있으면 지정된 키의 값을 바꿉니다. 사전에.
답변
먼저 질문에 답하려면 사전의 목적과 기본 기술을 살펴 봐야합니다.
Dictionary
KeyValuePair<Tkey, Tvalue>
각 값이 고유 키로 표시되는 목록입니다 . 좋아하는 음식 목록이 있다고 가정 해 보겠습니다. 각 값 (음식 이름)은 고유 한 키 (위치 =이 음식을 얼마나 좋아하는지)로 표시됩니다.
예제 코드 :
Dictionary<int, string> myDietFavorites = new Dictionary<int, string>()
{
{ 1, "Burger"},
{ 2, "Fries"},
{ 3, "Donuts"}
};
건강을 유지하고 마음이 바뀌었고 좋아하는 “버거”를 샐러드로 바꾸고 싶다고 가정 해 보겠습니다. 목록은 여전히 즐겨 찾기 목록이며 목록의 특성은 변경되지 않습니다. 당신이 가장 좋아하는 것은 목록에서 1 위를 유지하고 그 가치 만이 변할 것입니다. 이것은 당신이 이것을 부를 때입니다 :
/*your key stays 1, you only replace the value assigned to this key
you alter existing record in your dictionary*/
myDietFavorites[1] = "Salad";
하지만 당신이 프로그래머라는 사실을 잊지 마세요. 이제부터 당신의 문장은; 이모티콘은 컴파일 오류가 발생하고 모든 즐겨 찾기 목록이 0 인덱스 기반이기 때문에 사용을 거부합니다.
식단도 바뀌 었습니다! 따라서 목록을 다시 변경합니다.
/*you don't want to replace Salad, you want to add this new fancy 0
position to your list. It wasn't there before so you can either define it*/
myDietFavorites[0] = "Pizza";
/*or Add it*/
myDietFavorites.Add(0, "Pizza");
정의에는 두 가지 가능성이 있습니다. 이전에 존재하지 않았던 것에 대한 새로운 정의를 제공하거나 이미 존재하는 정의를 변경하려는 것입니다.
Add 메서드를 사용하면 레코드를 추가 할 수 있지만 한 가지 조건에서만이 정의에 대한 키가 사전에 없을 수 있습니다.
이제 우리는 내부를 살펴볼 것입니다. 사전을 만들 때 컴파일러는 버킷을 예약합니다 (레코드를 저장할 메모리 공간). 버킷은 사용자가 정의하는 방식으로 키를 저장하지 않습니다. 각 키는 버킷 (Microsoft에서 정의)으로 이동하기 전에 해시되며 값 부분은 변경되지 않습니다.
예제를 단순화하기 위해 CRC32 해싱 알고리즘을 사용하겠습니다. 정의 할 때 :
myDietFavorites[0] = "Pizza";
버킷으로 이동하는 것은 db2dc565 “Pizza”(간체)입니다.
다음을 사용하여 값을 변경할 때 :
myDietFavorites[0] = "Spaghetti";
다시 db2dc565 인 0을 해시합니다. 한 다음 버킷에서이 값을 찾아 거기에 있는지 확인합니다. 거기에 있다면 키에 할당 된 값을 다시 작성하면됩니다. 그것이 없으면 버킷에 값을 넣을 것입니다.
다음과 같이 사전에서 Add 함수를 호출 할 때 :
myDietFavorite.Add(0, "Chocolate");
0을 해시하여 값을 버킷의 값과 비교합니다. 버킷이 없는 경우에만 버킷에 넣을 수 있습니다 .
특히 문자열 사전이나 문자 유형의 키로 작업하는 경우 작동 방식을 아는 것이 중요합니다. 해싱이 진행되기 때문에 대소 문자를 구분합니다. 예를 들어 “name”! = “Name”. 이것을 묘사하기 위해 우리의 CRC32를 사용합시다.
“이름”
값 : e04112b1 “이름”값 : 1107fb5b
답변
예, 이것이 차이점입니다. 키가 이미 존재하는 경우 Add 메서드는 예외를 throw합니다.
Add 메서드를 사용하는 이유는 바로 이것입니다. 사전에 이미 키가 포함되어 있지 않은 경우 일반적으로 문제를 인식 할 수 있도록 예외를 원합니다.
답변
성능면에서 가능한 유사점보다 더 정확하고 가독성이 높은 코드를 사용하십시오.
나는 추가를 설명하는 작업을 느낍니다. 키의 존재는 이미 정말 드문 예외이므로 추가로 가장 잘 표현됩니다. 의미 론적으로 더 의미가 있습니다.
는 dict[key] = value
더 나은 대체를 나타냅니다. 이 코드가 보이면 어쨌든 키가 이미 사전에있을 것으로 예상합니다.
답변
하나는 값을 할당하고 다른 하나는 새 키와 값을 사전에 추가하는 것입니다.