2012-12-14 69 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; } 
    } 
} 

傳統Hashtable類

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<object, StringValueAttribute>

(此外,你在第二版中使用的Contains代替ContainsKey。雖然文檔中則狀態IDictionary.Contains應該看的鑰匙,所以我不完全知道爲什麼那並不't做你的期望。)

+0

它沒有按預期工作的原因是該方法被異步調用多次,所以最初的「Contains」檢查可能並不總能解決問題。我已經改變了方法,以允許這一點,它的工作原理。謝謝 –

+0

哦,在這種情況下,我建議你把整個東西包裝在一個'lock(stringValues){}'中。或者,「允許這個」就是這樣嗎? – Rytmis

+0

這正是我所做的。再次感謝 –