在C#中处理Hashtables时有没有办法避免转换?

时间:2011-07-29 18:19:31

标签: c# casting hashtable associative-array

我想知道是否有办法覆盖Hashtable(或Dictionary)类,因此它会自动对对象进行装箱/拆箱操作。换句话说:

myHashtable["value1"] = "this_is_string";
myHashtable["value2"] = 123;

string a = myHashtable["value1"];
int b = myHashtable["value2"];
// errors as expected, since i need to cast it to specific type from object

显然C#不允许用不同的类型覆盖 public T this [object key] 运算符,因为我试图做这样的事情:

public int this[object key] { get { return (base[key] as int); } set {} } // etc
public string this[object key] { get { return (base[key] as string); } set {} } // etc
// error

任何想法或提示在C#中使用关联数组时避免转换的最简单方法(如果有的话)(不需要严格使用Hashtable)?如果没有办法做到这一点,我会很感激,如果有一个比我更有知识的人,解释为什么会这样,以及它背后的基本原理。

谢谢。

修改: 我需要它的原因是我正在创建一个自定义的Settings类。设置可能具有不同类型的值,例如让“HowManyItemsToDisplay”具有某个整数值,而“NameOfSomeControl”将是一个字符串。因此,在编写类似以下内容时避免任何强制转换会很好:

myControl.Text = MySettings["SomeTextValue"];

while (MySettings["SomeIntValue"] > 0) { .. }

5 个答案:

答案 0 :(得分:5)

字典为您提供类型安全,您不能只是向它们扔东西。 HashTables不是通用的,并且使用对象,因此您必须使用box / unbox。简短的回答是您无法覆盖HashTable的此功能。答案是尽可能使用泛型。

除非您的目标是较旧的.net框架,否则我会坚持使用通用词典。

答案 1 :(得分:2)

假设您有充分的理由这样做,您可以编写一个扩展方法,以便以合理的方式模拟:

myHashTable.GetAs<string>("value1");
myHashTable.GetAs<int>("value2");

public static T GetAs<T>( this Hashtable ht, object key )
{
    return (T)ht[key];
}

如果您知道密钥始终是一个字符串,您可以将其作为密钥的参数类型,甚至可以使用通用字典或具有强类型密钥的其他结构。

并且非常清楚铸造和拳击仍在那里,只是隐藏在视野之外。

对编辑的其他回复:

如果你能够使用C#4我认为你几乎可以想要你想要Dictionary<object,dynamic>语法。当然,如果你能够做到这一点,那么你可能只想让设置对象动态化,而是使用语法mySettings.Value1

答案 2 :(得分:0)

您可以使用object.GetType()

动态投射

答案 3 :(得分:0)

C#是强类型的(好吧,他们正在弱化这个,但是它的核心......)

您通常使用指定键类型和值

的词典

您需要一个字典,其值可以是任何类型,并且仍然以类型安全的方式检索值。对我来说,这表明你正在尝试编写C#,好像它是一种弱类型的语言,使用哈希而不是创建一个类来存储相关值的集合。

在惯用的C#中,你很少有理由在同一个字典中存储不同的值类型。

答案 4 :(得分:0)

我认为如果您知道类型是预定义的,那么使用集合的通用版本总是很好:

列出而不是ArrayList,Array 字典而不是HashTable依次是KeyValuePair而不是对象

Stack&amp;的通用版本队列等。

重要的是,即使Microsoft BCL内部的许多遗留代码都使用非泛型集合,但对于新开发,泛型始终是首选。

即使您需要,也可以使用Generic Variance introduced with .NET 4.0