2011-02-10 2 views
1

은 내가 ConcurrentDictionary 있습니다, 실제 키 항목을 검색하는 데 사용되는 개체입니다하지만 대신에 단순히 키로 해시 코드를 사용하는ConcurrentDictionary.GetOrAdd() : 다른 서명을 가진 valueFactory

private static ConcurrentDictionary<int, string> _cd = new ConcurrentDictionary<int, string>(); 

는 보수적를하도록 (가능성이 큰) 객체 ISN ' t 키 :

public static string GetTheValue(Foo foo) 
{ 
    int keyCode = foo.GetHashCode(); // GetHashCode is overridden to guarantee uniqueness 

    string theValue = _cd.GetOrAdd(keyCode, FooFactory); 

    return theValue; 
} 

그러나 Factory에서 개체를 준비 할 때 Foo 개체에 다양한 속성이 필요합니다. GetOrAdd()의 valueFactory 매개 변수가 Func<int, string>을 예상하기 때문에 나는 내 푸 개체를 전달할 수 없습니다. 그렇게 할 수 전혀인가?

+2

그렇게하지 마십시오. HashCode는 고유하지 않습니다. 큰 개체를 사용해야합니다. 그것은 아무런 해를 끼치 지 않을 것입니다. – SLaks

+0

@SLaks : GetHashCode() 대신 ToString()을 사용한다고 가정합니다. – Bullines

+1

** **하지 마십시오. – SLaks

답변

2

내가 여기에 근본적인 오해가 있다고 생각 :

보수 할 수는 의 실제 키는 항목을 검색 할 객체 되어 사용할 수 있지만 대신 단순히 같은 해시 코드 를 사용 키가 이되도록 (잠재적으로 큰) 개체는 키가 아닙니다.

은 내가 당신이 관련되어 생각 생각하는 문구를 굵은 글씨로했습니다. 그들은 정말로 그렇지 않습니다. 사전이 너무 커서 키가 큰 개체이기 때문에 사전을 그리는 경우 틀린 모양입니다. 참조 형식 (C#의 class)의 경우 키는 사전에 참조으로 표시되며 이는 엄청난 정수의 크기입니다. 그리고 메소드간에 키를 전달하는 것에 관심이 있다면 다시 생각해보십시오. 객체 자체가 아닌 참조 만 복사되고 전달됩니다.

그래서 SLaks에 동의합니다. 먼저 Foo 유형 (또는 실제로는 무엇이든)을 키로 사용하십시오. 그것은 당신의 삶을 훨씬 더 단순하게 만들 것입니다.

3

큰 개체를 키로 사용하는 데는 아무런 문제가 없습니다.

개체가 struct (그리고 구조체가 아니어야합니다.)이 아니라면 절대로 복사되지 않습니다.
나중에 볼 수있게하려는 경우, 개체가 분명히 주위에 stcik되므로 메모리가 누출되지는 않습니다.

합리적인 (또는 상속 된) GetHashCode()Equals() 구현이 있으면 성능에 영향을주지 않습니다.

+0

호기심에서 벗어나 OP가 큰 것으로 지정했기 때문에 "구조체가되어서는 안됩니다"라고 말하고 있습니까?아니면 사용자 지정 값 형식을 일반적으로 키로 사용하면 안된다는 말입니까? 저는 전자를 추측하고 있습니다. 단지 확신하고 싶습니다. –

+0

@ Dan : 수정하십시오. – SLaks

0

다른 이유가 필요했습니다. 다른 사람이 여기처럼 끝내면 내가 할 수있는 방법이 있습니다.

public static string GetTheValue(Foo foo) 
{ 
    int keyCode = ... 

    string theValue = _cd.GetOrAdd(keyCode, (key => FooFactory(foo))); //key is not used in the factory 

    return theValue; 
} 
관련 문제