C# 从Silverlight哈希表到IDictionary的转换问题

C# 从Silverlight哈希表到IDictionary的转换问题,c#,.net,silverlight,collections,dictionary,C#,.net,Silverlight,Collections,Dictionary,我目前正在更新一些现有的Silverlight代码,并将助手类移动到Silverlight 5库中,但我正在努力将哈希表实现更改为IDictionary实现,如下所示 此功能允许对枚举进行属性化,从而允许查找字符串值 代码进行编译,但在stringValues.Add(value,attrs[0])上失败行 知道我在代码转换过程中做错了什么吗 例外情况 The value "Today" is not of type "System.Type" and cannot be used in thi

我目前正在更新一些现有的Silverlight代码,并将助手类移动到Silverlight 5库中,但我正在努力将哈希表实现更改为IDictionary实现,如下所示

此功能允许对枚举进行属性化,从而允许查找字符串值

代码进行编译,但在
stringValues.Add(value,attrs[0])上失败ParseEnumStrings
类中的code>行

知道我在代码转换过程中做错了什么吗

例外情况

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 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();
枚举

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实现

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 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();

问题是,词典的
TKey
System.Type
,但您希望使用枚举的值作为键。字典的类型可能应该是
IDictionary


(另外,在第二个版本中,您使用的是
Contains
,而不是
ContainsKey
。虽然文档中确实指出
IDictionary.Contains
应该查看键,所以我不完全确定这为什么没有达到您的预期。)

问题是,词典的
TKey
System.Type
,但您希望使用枚举的值作为键。字典的类型可能应该是IDictionAry,它修复了add问题,但突出显示了另一个问题。IDictionary上的contains方法的工作方式是否与哈希表相同?它找不到现有的项目。请注意您在原始版本中如何使用
ContainsKey
,但在新版本中如何使用
Contains
。找到了它。请把你的评论作为回答,我会接受的。感谢您的帮助。它无法按预期工作的原因是该方法被异步调用了多次,因此初始的“Contains”检查可能并不总能发现问题。我已经改变了方法,以允许这一点,它的工作。谢谢,在这种情况下,我建议您将整个内容包装在
锁(stringValues){}
中。或者也许“允许这样”就是那样?我就是这么做的。再次感谢