如何访问Hashtable中的Structure属性?

时间:2016-01-15 00:10:50

标签: c# struct hashtable

我有以下代码修改结构内的属性,结构在哈希表中。散列表中的每个项都有(Int)数据类型的键和(struct Bag)的键,这里是我的代码:

struct Bag {

  string apple_type;
  string orange_type;

};

 // Make a new hashtable that will have a key of (int) data type, value of (Bag)
   public static Hashtable bags = new Hashtable();

然后我有一个方法将从数据库读取行读取数据并添加,只要有一行它将一个项目(bag(object))添加到哈希表:

public void initHashtbl(){


OleDbConnection db_connector = new OleDbConnection(connection_string);

            // Open connection to oracle
            db_connector.Open();

            OleDbCommand sql_commander = new OleDbCommand(sql_statement, db_connector);

            OleDbDataReader data_Reader = sql_commander.ExecuteReader();


            // Read data from sql db server and store it in memory ...


            Bag tempBag = new Bag();

            // row counter used for list view
            int row_counter = 0;

            while (data_Reader.Read()) { // Keep reading data from memory until there is no row

      tempBag.apple_type = data_Reader[0].ToString();

      bags.Add(row_counter, tempBag);
      row_counter++;
}


   for(int bag_item=0;bag_item < bags.Count;bag_item++){

         // Get orange type value from another method that uses another sql statement from another table in db ..
     ((bag) bags[bag_item]).orange_type = getOrangeType(((bag) bags[bag_item]).apple_type);    
}

}

如果我想访问它,如何在以后访问已经在哈希表内的结构的属性?

编辑: 我收到此错误: &#34;无法修改取消装箱转换的结果。&#34;

3 个答案:

答案 0 :(得分:0)

这段代码让我阅读了一个项目:

Θ(n^2)

要修改项目,我认为您必须创建一个新的Bag并替换现有的Bag:

        string orangeType = ((Bag) bags[0]).orange_type;

如果您尝试在HashTable中修改行李的属性,则会收到上面报告的错误。

答案 1 :(得分:0)

  

词典不允许我直接修改

Hashtable也不会。这与Hashtable vs Dictionary无关。问题是你的价值&#34;在任何一种情况下都是值类型,因此无法在集合中直接修改。如果确实需要一个结构,那么您必须创建一个 new 值并将其返回到哈希表中:

bags.Add(1, new Bag() {apple_type="apple1",orange_type="orange1"});

//((Bag)bags[1]).apple_type="apple2";
var bag = (Bag)bags[1];
bag.apple_type = "appple2";
bags[1] = bag;

但是可变结构通常是坏的,所以我要么在第一个时间内得到结构的值(而不是在初始加载循环中修改它):

// row counter used for list view
int row_counter = 0;

while (data_Reader.Read()) { // Keep reading data from memory until there is no row
{
    var appleType = data_Reader[0].ToString();
    Bag tempBag = new Bag() {
        apple_type = appleType,
        orange_type = getOrangeType(appleType)
        };
    bags.Add(row_counter, tempBag);
    row_counter++;
}

或使用class

请注意,无论您使用Hashtable还是Dictionary,相同的代码的工作方式都完全相同。

另外,因为你的&#34;键&#34;只是一个递增的数字(并没有与价值挂钩),您也可以使用List<Bag>并按索引访问项目。

答案 2 :(得分:0)

由于价值类型的工作原理,盒装行李是原件的副本,而且#34;取消装箱&#34;它通过铸造回到Bag创建了另一个副本。 From the C# language spec

  

当值类型的值转换为类型对象时,为对象   实例,也称为“盒子”,被分配来保存值,并且   值被复制到该框中。相反,当对象引用时   转换为值类型,检查引用的对象是否为   正确值类型的框,如果检查成功,则为该值   在框中被复制出来。

修改副本无论如何都不会改变原件,因此允许它是没有意义的。

<强>更正:

要修复错误并允许修改您的HashTable of Bag,您应该将值类型更改为引用类型:

    public class Bag
    {
        public string apple_type { get; set; }
        public string orange_type { get; set; }
    };