你的位置:首页 > ASP.net教程

[ASP.net教程]struct对象可能分配在托管堆上吗


 

struct对象可能被分配在托管堆上吗?

--会的。

 

比如当对struct装箱的时候,就会被分配在托管堆上。

 

比如,让一个struct实现一个接口。

 

  public interface IReport
  {
    string Name { get; }
  }
  public struct Score : IReport
  {
    public string Name
    {
      get { return "80分来自struct"; }
    }
  }

 

再来一个类负责打印接口属性值的类和方法。

 

  public class Tester
  {
    public void Test(IReport report)
    {
      Console.WriteLine(report.Name);
    }
  }

 

然后在Main方法中如下调用:

 

    static void Main(string[] args)
    {
      var tester = new Tester();
      tester.Test(new Score());
      Console.ReadKey();
    }

 

现在,我们想查看在这过程中,struct是否发生了装箱。

 

打开"VS2012开发人员命令提示"。

 

导航到exe文件所在的文件夹,然后用ildasm反编译,把IL代码输出到一个1.txt文件中。

 

1

 

我们看到,对struct对象进行了装箱。

 

2

 

那么,如何避免装箱呢?

 

可以在Tester类中,增加一个泛型方法。

 

  public class Tester
  {
    public void Test(IReport report)
    {
      Console.WriteLine(report.Name);
    }
    public void TestGeneric<T>(T report) where T : IReport
    {
      Console.WriteLine(report.Name);
    }
  }

 

然后在Main方法中使用泛型方法。

 

    static void Main(string[] args)
    {
      var tester = new Tester();
      tester.TestGeneric(new Score());
      Console.ReadKey();
    }

 

再次运行,再次反编译,查看IL代码:

 

3

 

我们发现,struct已不再装箱。

 

Why?

 

在泛型方法中限定了方法参数的类型,struct满足类型的要求。当把struct对象作为实参传入时,泛型方法直接使用struct,而不是IReport,从而避免了struct的装箱。