【问题标题】:Arrays in Generic class泛型类中的数组
【发布时间】:2009-11-24 04:55:00
【问题描述】:

在泛型类中使用数组有什么缺点吗?如果是,它们是什么?如果没有,有什么优势?

【问题讨论】:

    标签: .net arrays generics c#-2.0


    【解决方案1】:

    我能想到的在泛型类中使用数组的主要优点是避免装箱。具体来说,当您将值类型(“原始”,如 Int32、Boolean 等)转换为对象时,运行时必须将值类型实例包装在引用类型(“框”它)中并将其放在托管堆。这使得将值类型作为引用类型访问比直接作为值类型访问效率要低得多。

    如果你有

    class MyGenericContainer<T>
    {
        private T[] array;
    }
    

    然后你实例化MyGenericContainer&lt;int&gt;,你会得到一个int实例数组,当你访问它们时不会被装箱。

    另一方面,如果你有

    class MyContainer
    {
        private object[] array;
    }
    

    即使您当然可以将整数添加到数组中,它也会被装箱,因此访问它的效率会降低,并且存储它的行为涉及更多的存储空间。具体来说,每个数组都将存储对其项目的引用(4 个字节?)。在使用值类型参数化的一般情况下,指针将指向作为字段存在于托管堆上的父对象中的值类型。在非通用情况下,指针将引用托管堆上父对象内的对象包装器,该对象包装器将在内部引用堆上其他位置的值类型实例。因此,在对值类型进行装箱时,您会获得额外的对象和引用的开销。访问也涉及更多开销,但取决于特定的用例,这很复杂。

    【讨论】:

    • 当然,但这是泛型的优势,而不是泛型类中的数组。
    • 好点。但是在泛型类中使用数组是否有优点或缺点,这些优点或缺点不是泛型的优点(一般来说 (c:) 而是数组本身不被相同的非泛型类共享?跨度>
    【解决方案2】:

    性能方面是对象的装箱和拆箱。即将对象转换回其原始类型的开销。

    在可读性方面,如果您在集合中指定类型,它会使代码更具可读性。

    【讨论】:

      【解决方案3】:

      好的, 简而言之,泛型更快,并为您提供了一种更灵活的方法来使用 C# 等强类型语言。您正在给编译器一个编译时大小提示(它不必在运行时发现它)它包含一些类“T”列表。但这只是开始。 .你可以有通用的类和方法。 . .您可以使用 where 语句来限制类型。这是一个例子(不,我没有编译它......它不会编译......这仅用于演示目的)对不起,如果它真的很清楚。 . .它已经过了我的就寝时间了!

      Called like: 
      

      CoolOps op = new CoolOp();

         IOtherCoolInterace oci = DoThisVeryCoolThing<IOtherCoolInterace,CoolOps>(op);
      
      public T DoThisVeryCoolThing<T,U>(U whatIAm) where U: IMyVeryCoolInterface where T: IOtherCoolInterface  // I'm restricting the type that can be operated on and returned
      {
          T thingToReturn  = default(T);
      
          if(whatIAm == null) return thingToReturn;
      
          try
          {
              thingsToReturn = whatIAm.DoSomeWorkOnTheInterface(); 
      
          }
          catch(Exception ex) { ... // do exception stuff here }
      
          return thingToReturn;  // return work done
      }
      
      public interface IMyVeryCoolInterface
      {
          IOtherCoolInterface DoSomeWorkOnTheInterface();
          . . .
      }
      
      // My operation must implement this interace
      public class CoolOps : IMyVeryCoolInterface
      {
           . . . 
         IOtherCoolInteface DoSomeWorkOntheInterface()
         {
            return xxx;
         }
      }
      

      等等等等……

      在必须实现接口(我的合同!)IMyVeryCoolInterface 并且该接口包含返回必须实现 IOtherCoolInterface 的对象实例的方法调用上的 U 实例上做一些工作。
      这在现实世界中如何运作?这使您可以设置一种通用方法来处理许多不同类型的工作。因此,如果您有许多描述操作的类,则可以如上所述以“通用”方式调用这些操作。这避免了重复的容易出错的代码,其中类似的方法被一遍又一遍地编写,这些方法仅根据类型进行非常细微的不同操作(例如,用于图像模糊的不同算法) - 但方式略有不同。例如** 我们知道我们将对图像进行图像操作,但让我们参数化图像类型(jpeg、png 等)和算法(5x5、3x3 卷积等)并编写一次方法 ** 或类似的效果。 . .

      我希望这会有所帮助。 . .

      博学的穴居人

      【讨论】:

        【解决方案4】:

        在泛型中使用数组与在任何其他非泛型类中使用它们并没有什么特别之处。优点(内存占用、按索引直接访问等)和缺点(插入价格、增长价格)是相同的。

        在内部,CLR 将任何泛型转换为具体的类型表示,因此使用泛型数组与标准类型化数组没有区别。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-20
          • 2021-12-01
          • 2015-08-26
          • 2018-05-25
          • 1970-01-01
          • 1970-01-01
          • 2011-06-13
          • 1970-01-01
          相关资源
          最近更新 更多