2012-12-14 4 views
0

현재 일부 Silverlight 코드가 나오고 도우미 클래스가 Silverlight 5 라이브러리로 옮겨지고 있지만 아래 그림과 같이 HashTable 구현에서 IDictionary 구현으로 변경하는 데 어려움을 겪고 있습니다.Silverlight HashTable에서 IDictionary로 변환 할 때의 문제

이 기능을 사용하면 열거 형을 특성화하여 문자열 값을 찾을 수 있습니다.

코드가 컴파일되지만 ParseEnumStrings 클래스의 stringValues.Add(value, attrs[0]); 줄에 예외가 발생하지만 예외는 발생하지 않습니다.

코드 변환에서 내가 잘못한 점은 무엇입니까?

예외

The value "Today" is not of type "System.Type" and cannot be used in this generic collection. 
Parameter name: key. 

    at System.ThrowHelper.ThrowWrongKeyTypeArgumentException(Object key, Type targetType) 
    at System.Collections.Generic.Dictionary`2.System.Collections.IDictionary.Add(Object key, Object value) 
    at Silverlight.Helper.Enums.ParseEnumStrings.GetStringValue(Enum value) in Z:\Perforce\Development\Microsoft .Net\dotNet 4.0\Silverlight 5\Helper\Helper\Enums\ParseEnumStrings.cs:line 25 
    at QSmartFaultsByZone.Web.Models.QSmartService.GetRTF(Int32 buID, String zones, ReportTimePeriod time) in Z:\Perforce\Development\Microsoft .Net\dotNet 4.0\Silverlight 5\QSmart Faults By Zone\QSmartFaultsByZone.Web\Models\QSmartService.cs:line 114 
    at GetRTF(DomainService , Object[]) 
    at System.ServiceModel.DomainServices.Server.ReflectionDomainServiceDescriptionProvider.ReflectionDomainOperationEntry.Invoke(DomainService domainService, Object[] parameters) 
    at System.ServiceModel.DomainServices.Server.DomainOperationEntry.Invoke(DomainService domainService, Object[] parameters, Int32& totalCount) 
    at System.ServiceModel.DomainServices.Server.DomainService.Query(QueryDescription queryDescription, IEnumerable`1& validationErrors, Int32& totalCount) 

열거

public enum ReportTimePeriod 
{ 
    [StringValue("Today")] 
    Today = 0, 
    [StringValue("Twenty Four Hours")] 
    TwentyFourHours = 1, 
    [StringValue("Week")] 
    Week = 2, 
    [StringValue("Month")] 
    Month = 3 
} 

문자열 값은 속성

public class StringValueAttribute : Attribute 
{ 
    private readonly string value; 

    public StringValueAttribute(string value) 
    { 
     this.value = value; 
    } 

    public string Value 
    { 
     get { return this.value; } 
    } 
} 

기존 해시 클래스

public class ParseEnumStrings 
{ 
    private static Hashtable _stringValues = new Hashtable(); 

    public static string GetStringValue(Enum value) 
    { 
     string output = null; 
     Type type = value.GetType(); 

     //Check first in our cached results... 
     if (_stringValues.ContainsKey(value)) 
      output = (_stringValues[value] as StringValueAttribute).Value; 
     else 
     { 
      //Look for our 'StringValueAttribute' 
      //in the field's custom attributes 
      FieldInfo fi = type.GetField(value.ToString()); 
      StringValueAttribute[] attrs =fi.GetCustomAttributes(typeof(StringValueAttribute),false) as StringValueAttribute[]; 
      if (attrs.Length > 0) 
      { 
       _stringValues.Add(value, attrs[0]); 
       output = attrs[0].Value; 
      } 
     } 

     return output; 
    } 

새로운 IDictionary 구현

public class ParseEnumStrings 
{ 
    private static IDictionary stringValues = new Dictionary<Type, StringValueAttribute>(); 

    public static string GetStringValue(Enum value) 
    { 
     string result = string.Empty; 
     Type type = value.GetType(); 

     if (stringValues.Contains(value)) 
      result=(stringValues[value] as StringValueAttribute).Value; 
     else 
     { 
      FieldInfo f = type.GetField(value.ToString()); 
      StringValueAttribute[] attrs = f.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 
      if (attrs.Length > 0) 
      { 
       stringValues.Add(value, attrs[0]); 
       result = attrs[0].Value; 
      } 
     } 

     return result; 
    } 
} 

구현

return (from rft in qs.spBusinessProductsRFTTodayV2(zones, buID, ParseEnumStrings.GetStringValue(time)) 
     select new RightFirstTimeReportDto 
     { 
      Builds=rft.Builds, 
      BuildsWithFaults=rft.BuildsWithFaults, 
      Name=rft.Name, 
      RightFirstTime=rft.RFT, 
      ZoneID=rft.ZoneID 
     }).ToList(); 
+1

문제는 사전의'TKey'가'System.Type'이지만 열거 형의 값을 키로 사용하려고한다는 것입니다. 사전의 형식은 IDictionary Rytmis

+0

이어야합니다. 추가 문제가 해결되었지만 다른 항목이 강조 표시되었습니다. IDictionary의 contains 메소드가 HashTable과 같은 방식으로 작동합니까? 해당 항목을 찾을 수 없습니다. –

+0

원본에서'ContainsKey'를 어떻게 사용하고 있는지, 새 버전에서는'Contains'를 사용하고 있는지 확인하십시오. – Rytmis

답변

1

문제는, 당신의 사전의 TKeySystem.Type이지만, 당신이 기다리고있어 사용 열거 형 값을 키로 사용하십시오. 문서가 IDictionary.Contains이 키를 보라 그 상태가 없지만 사전의 유형은 아마.

IDictionary<object, StringValueAttribute>은 (또한, 두 번째 버전에서 Contains 대신 ContainsKey의를 사용하고 있어야한다, 그래서 아무튼 내가 왜 완전히 확실하지 않다

+0

예상대로 작동하지 않는 이유는 메서드가 비동기 적으로 여러 번 호출되어 초기 '포함'검사가 항상 문제를 파악하지 못할 수 있기 때문입니다. 나는 이것을 허용하는 방법을 변경했으며 작동한다. 감사합니다 –

+0

오, 그 경우에는'lock (stringValues) {}'안에 모든 것을 감쌀 것을 제안합니다. 또는 아마도 "이것을 허용"하는 것이 정확히 무엇입니까? – Rytmis

+0

정확히 내가 한 일. 다시 한 번 감사드립니다. –

관련 문제