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文件中。
我們看到,對struct對象進行了裝箱。
那麼,如何避免裝箱呢?
可以在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代碼:
我們發現,struct已不再裝箱。
Why?
在泛型方法中限定了方法參數的類型,struct滿足類型的要求。當把struct對象作為實參傳入時,泛型方法直接使用struct,而不是IReport,從而避免了struct的裝箱。