【问题标题】:How to avoid boxing and if or Switch statements如何避免装箱以及 if 或 Switch 语句
【发布时间】:2014-04-05 20:34:07
【问题描述】:

假设我有以下对象:

object[] objs = new object[3]{ "this is sample string", 42L, 1}; 

我想对数组中的单个对象做一些事情,比如

foreach (object o in objs)
{
   /// logic here 
     mylogic();
}

现在mylogic() 将只接受对象参数,因此正在进行装箱,但我们需要能够根据对象的类型做一些事情,所以我们会做类似的事情:

public void dosomething(object obj)
{ 
   // one way
   if(obj.GetType() == typeof(string))
   {
      // string specific something
   }
   // another way
   if(obj is long)
   {
      // long specific something
   }

}

嗯,它很丑而且没有性能,有没有更好的方法可以使用泛型或任何其他方式?

【问题讨论】:

  • 丑陋开始于object[] objs = new object[3]

标签: c# .net asp.net-mvc c#-4.0 generics


【解决方案1】:

您的值已经装箱,因为它们存储在object[] 中。因此,当您将它们传递给采用 object 参数的方法时,不会发生额外的装箱。

object[] 是我重点关注的地方 - 真的有必要这样表示您的数据吗?你真的不知道它们的结构吗?最好定义一个类(或结构)来保存您的数据,并包含作用于数据的方法 - 然后您在设计和编译时知道每个字段或属性的类型,并且您可以使用此信息在进一步的代码中。在您的情况下,可能看起来像:

class Container
{
    public string StringProperty { get; set; }
    public long LongProperty { get; set; }
    public int IntProperty { get; set; }

    public void DoSomething()
    {
        // string specific something with StringProperty
        // long specific something with LongProperty
        // int specific something with IntProperty
    }
}

这样您就可以开始封装您的数据,并确保它靠近使用它们的逻辑。更好的办法是将属性设置为私有只读字段,这样它们甚至对外部都不可见。

【讨论】:

    【解决方案2】:

    您可以尝试在 C# 4.0 及更高版本中使用 dynamic 关键字,看看是否对您有帮助。最好定义自己的类并创建不同类型的属性,然后直接使用它们。

    内存开销将最小化,并且您可以避免所有的拳击惩罚。

    【讨论】:

      【解决方案3】:

      IMO,在这种情况下应该问一个问题:代码设计有什么问题吗?包含不同类型对象的数组的想法是什么?它们代表什么?可能您需要一个单独的类来保存这些不同的对象...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多