【问题标题】:How can i access Structure property that is inside Hashtable? [duplicate]如何访问 Hashtable 中的 Structure 属性? [复制]
【发布时间】:2016-01-15 00:10:50
【问题描述】:

我有以下代码将修改结构内的属性,并且该结构位于哈希表内。哈希表中的每个项目都有(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);    
}

}

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

编辑: 我收到此错误: "无法修改拆箱转换的结果。"

【问题讨论】:

  • 您是否仅限于使用哈希表?还有其他可以使用 Dictionary 的结构,例如,您只需提供 bag[key].orange_type
  • 是的,我遇到了一个错误,对不起,我忘了把它添加到问题帖子中,我现在已经修改了,你现在应该可以看到了。
  • 字典不允许我直接修改它,我希望能够直接修改它以供以后使用,使用字典我必须将一个变量传递给它将加载数据的变量。如果我使用字典,如下所示:bag.TryGetValue(bag_item, out tempBag);

标签: c# struct hashtable


【解决方案1】:

字典不允许我直接修改

Hashtable 也不会。这与HashtableDictionary 无关。问题在于,无论哪种情况,您的“值”都是值类型,因此您不能直接在集合中修改它。如果您真的需要一个结构,那么您必须创建一个值并将其返回到哈希表中:

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,相同代码的工作方式完全相同。

此外,由于您的“键”只是一个递增的数字(根本不与值绑定),您也可以使用 List&lt;Bag&gt; 并按索引访问项目。

【讨论】:

    【解决方案2】:

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

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

    要修改一个项目,我认为你必须创建一个新的包并替换现有的包,如下所示:

            bags[0] = newBag;
    

    如果你尝试在HashTable中修改一个bag的属性,那么你会得到上面报的错误。

    【讨论】:

      【解决方案3】:

      由于值类型的工作原理,装箱的 Bag 是原始 Bag 的副本,并且通过强制转换回 Bag 来“拆箱”它会创建另一个副本。 From the C# language spec:

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

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

      更正:

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

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

      【讨论】:

        猜你喜欢
        • 2012-07-02
        • 1970-01-01
        • 1970-01-01
        • 2013-05-25
        • 2014-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多