struct对象可能分配在托管堆上吗_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > struct对象可能分配在托管堆上吗

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

 2015/5/15 3:12:55  Darren Ji  程序员俱乐部  我要评论(0)
  • 摘要:struct对象可能被分配在托管堆上吗?--会的。比如当对struct装箱的时候,就会被分配在托管堆上。比如,让一个struct实现一个接口。publicinterfaceIReport{stringName{get;}}publicstructScore:IReport{publicstringName{get{return"80分来自struct";}}}再来一个类负责打印接口属性值的类和方法。publicclassTester{publicvoidTest(IReportreport)
  • 标签:

 

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

--会的。

 

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

 

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

 

monospace; width: 100%; margin: 0em; background-color: #f0f0f0">    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的装箱。

  • 相关文章
发表评论
用户名: 匿名