2010-01-19 4 views
1

나는 위의 두 줄을 검색 한 키를 사용하고 있는데도 KeyNotFoundException을 얻는 이유는 다음과 같습니다. 아무도 이것이 작동하지 않을 상황을 알고 있습니까? 나는 혼란 스럽다. BTW 'SchemaElementType 열거 형입니다.이전에 키 모음에서 가져온 키를 사용할 때 KeyNotFoundException이 발생합니까?

public class DefaultValue 
{ 
private Dictionary<Parameter, string> _params; 

public DefaultValue(Dictionary<Parameter, string> parameters) 
{ 
     _params = parameters; 
} 

    public string GetParameterValue(string name) 
    { 
     foreach(Parameter param in _params.Keys) 
     { 
      if(param.ParamName.Equals(name)) 
      { 
       // **** Issue here **** 
       return _params[param]; 
      } 
     } 
     return string.Empty; 
    } 
} 

[DataContract] 
public class Parameter 
    { 
     #region Members 
     private Guid _guid; 
     private Guid _formulaGuid; 
     private string _name; 

     #endregion 

     #region Constructor 
     public Parameter(Guid guid, Guid formulaGuid, string name, SchemaElementType type) 
     { 
      ParamGuid = guid; 
      FormulaGuid = formulaGuid; 
      ParamName = name; 
      ParamType = type; 
     } 

     public Parameter() 
     {} 

     #endregion 

     #region Properties 

     [DataMember] 
     public Guid ParamGuid 
     { 
      get { return _guid; } 
      set { _guid = value; } 
     } 

     [DataMember] 
     public Guid FormulaGuid 
     { 
      get { return _formulaGuid; } 
      set { _formulaGuid = value; } 
     } 

     [DataMember] 
     public string ParamName 
     { 
      get { return _name; } 
      set { _name = value; } 
     } 

     [DataMember] 
     public SchemaElementType ParamType { get; set; } 

     #endregion 

     #region Overrides 

     public bool Equals(Parameter other) 
     { 
      if (ReferenceEquals(null, other)) return false; 
      if (ReferenceEquals(this, other)) return true; 
      bool result =other._guid.Equals(_guid); 
      result = result && other._formulaGuid.Equals(_formulaGuid); 
      result = result && Equals(other._name, _name); 
      result = result && Equals(other.ParamType, ParamType); 

      return result; 
     } 

     public override int GetHashCode() 
     { 
      unchecked 
      { 
       int result = _guid.GetHashCode(); 
       result = (result*397)^_formulaGuid.GetHashCode(); 
       result = (result*397)^(_name != null ? _name.GetHashCode() : 0); 
       result = (result*397)^ParamType.GetHashCode(); 
       return result; 
      } 
     } 

     public override bool Equals(object obj) 
     { 
      if (ReferenceEquals(null, obj)) return false; 
      if (ReferenceEquals(this, obj)) return true; 
      if (obj.GetType() != typeof (Parameter)) return false; 
      return Equals((Parameter) obj); 
     } 

     #endregion 
    } 
+0

실제로 문제가 발생했음을 보여주는 코드가 있습니까? –

답변

0

그들 사이에 불일치가 있는지 때

foreach(var item in _params) 
{ 
    if(item.Key.ParamName.Equals(name)) 
    { 
     return item.Value; 
    } 
} 
+0

흠, var abuse :) varValuePair 을 사용하여 var를 사용해야합니다. C#을 참조),하지만 난 다른 곳에서 일어나는 또 다른 토론 thats 같아요 :) – Wayne

+2

@Wayne - 이것은 분명히 주관적인 포인트이지만, 어떤 추가 정보가 당신에게 말할 것 인가? 왜 코드를 어지럽히 는가? IMO의'var' 사용법은 완벽하고 분명합니다. –

+0

Mark와 Rune FS에 모두 투표를했지만, Parameter 클래스의 코딩/사용법을 개선해야 할 필요성을 강조 했으므로 버그 수정 (긴밀한 일정)을 얻는 데 도움이되었으므로이를 답변으로 표시했습니다. 열쇠로서. 나는이 변화를 최대한 빨리 도입 할 수있게 될 것입니다. 고마워. –

1

잘 엄격하게 당신이 위의 몇 줄의 어떤 시점에서 해시 키를 계산하는 데 사용되었다 객체를 불러 오는하는 (검색 키)를 검색하지 않는 말.

사전에 삽입하면 키 개체의 GetHashKey 메서드가 호출됩니다. 키 - 값 쌍을 삽입 한 시점부터 코드가 실행되는 시점까지 변경되면 설명 된 동작이 발생합니다. (GetHashKey no가 다른 키 - 값 쌍에 키와 일치하는 값을 반환하는 경우를 제외하고).

해시 키의 값을 찾을 때 삽입 불러 오는 및 당신은 KeyValuePair <> 클래스를 이용할 수

+0

에서 변경하면 ... 시간이 없어야합니까? 그게 니가 의미 한 것 같은데? – Wayne

+0

@Wayne 당신은 수정하고 내가 변경 한 tu를 만들었습니다 –

2

내가 Parameter가 변경할 수 있다는 사실 걱정이. 사전에 (을 추가 한 후 )을 입력하면 GetHashCode() (즉 모두)을 생성 할 때 사용 된 값이 변경된 후 모든 배팅이 해제되고 이 아닌 것으로 확인되면 항목을 다시 볼 수 있습니다. 매개 변수를 변경하여 나누기 예를 들어

[DataMember] 
    public string ParamName { get; private set; } 

: 나는 아마 명시 적 필드를 삭제하고 C# 3.0 자동으로 구현 된 속성을 사용하는 것, 즉, Actaully

[DataMember] 
    public string ParamName // applies to all the properties, not just this one 
    { 
     get { return _name; } 
     private set { _name = value; } 
    } 

이 공개 세터을하지 않을 :

var data = new Dictionary<Parameter, string>(); 
    Parameter p; 
    data.Add((p = new Parameter(Guid.NewGuid(), Guid.NewGuid(), "abc", 
     SchemaElementType.A)), "def"); 
    var dv = new DefaultValue(data); 
    string val1 = dv.GetParameterValue("abc"); // returns "def" 
    p.ParamGuid = Guid.NewGuid(); 
    string val2 = dv.GetParameterValue("abc"); // BOOM 

마지막 생각으로; 전형적인 사용법이 string에 의해 찾아보기 인 경우에, 이름을 내부 사전을위한 열쇠로 사용하지 않겠습니까? 현재 귀하는 사전을 올바르게 사용하지 않습니다.

+0

나는 매개 변수 키가 추가와 가져 오기 사이에서 전혀 변경되지 않았 음을 확신하지만 나는 확인할 것이다. 나는 단지 다른 사람으로부터 코드를 집어 들었으므로 사용법을 아직 완전히 알지 못했다. 구현에 대한 귀하의 생각에 완전히 동의하고 변경 작업의 영향에 액세스해야합니다. –