2017-08-29 40 views
8

我正在試驗新的C#7功能,並且發現了一些奇怪的東西。 考慮以下簡化方案:如果內部方法也接受C#7中的參數,爲什麼不可能鏈接ref返回?

public struct Command 
{ 
} 

public class CommandBuffer 
{ 
    private Command[] commands = new Command[1024]; 
    private int count; 

    public ref Command GetNextCommand() 
    { 
     return ref commands[count++]; 
    } 

    public ref Command GetNextCommand(out int index) 
    { 
     index = count++; 
     return ref commands[index]; 
    } 
} 

public class BufferWrapper 
{ 
    private CommandBuffer cb = new CommandBuffer(); 

    // this compiles fine 
    public ref Command CreateCommand() 
    { 
     ref Command cmd = ref cb.GetNextCommand(); 
     return ref cmd; 
    } 

    // doesn't compile 
    public ref Command CreateCommandWithIndex() 
    { 
     ref Command cmd = ref cb.GetNextCommand(out int index); 
     return ref cmd; 
    } 
} 

爲什麼第二種方法給我下面的編譯器錯誤?

CS8157 Cannot return 'cmd' by reference because it was initialized to a value that cannot be returned by reference 

我知道的編譯器不能讓你一個參考返回,可能最終會被死以後一個變種,但我實在不明白如何具有附加了PARAM任何改變了這一局面辦法。

+8

這是一個稱爲「指針別名」的通用編譯器問題。 C或C++編譯器中的優化器必須解決這個問題,並且趨於流行。基本問題是'out'參數允許可觀察到的副作用,可以使參考無效。證明如賦值不會使cmd無效是非常困難的事情。事實上,cmd不再引用命令[index]。在這種情況下,你會說「沒問題」,C#編譯器說「不太確定,我們不要」。否則,Fortran仍然相關的基本原因以及爲什麼需要很長時間才能添加ref。 –

+1

Gotcha。所以基本上有一些情況是,out參數可能會導致後面的參考無效,所以編譯器會使所有這些方法變得非法,而不是試圖分析它們,因爲這不是一個真正可靠的過程。 – loodakrawa

回答

0

你不能調用具有ref或out PARAM

這種變化可以修復它

public ref Command CreateCommandWithIndex(out int index) 
     { 
      ref Command cmd = ref cb.GetNextCommand(out index); 
      return ref cmd; 
     } 

那麼當你調用這個方法,通過數值稱之爲裁判返回方法

相關問題