2017-08-29 71 views
8

Yeni C# 7 özelliklerini denedim ve garip bir şey buldum.İç yöntem C# 7'deki paramları da kabul ederse neden ref dönüşlerini zincirlemek mümkün değil?

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; 
    } 
} 

Neden İkinci yöntem bana aşağıdaki derleyici hata veriyor: aşağıdaki basitleştirilmiş senaryoyu göz önüne alındığında?

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

Ben derleyici daha sonra ölmüş bitebileceğini bir var bir ref dönmek için izin veremez biliyorum ama gerçekten nasıl param out ek sahip bkz herhangi Bu senaryoyu değiştirir yok yol.

+8

Öyle "işaretçi takma" adı verilen genel derleyici problemi. Bir C veya C++ derleyicisindeki en iyileştiricinin çözmesi ve flubeye eğilimi olması gereken problem. Temel sorun, 'out' argümanının referansı geçersiz kılan gözlenebilir bir yan etkiye izin vermesidir. Ödevin cmd'yi geçersiz kılmadığını kanıtlamak çok zor. Ve aslında, cmd artık komutları [index] referans almıyor. Bu durumda "sorun değil" diyeceksiniz, C# derleyici "emin değil," değil diyor. Aksi taktirde Fortran'ın hala niçin geçerli olduğu ve neden ref eklenmek için uzun zaman almasının temel nedenleri. –

+1

Gotcha. Bu nedenle, temel olarak, bir dış parametrenin referansı geçersiz kılabileceği senaryolar vardır, bu yüzden derleyici, tüm bu yöntemleri analiz etmeyi denemek yerine yasadışı kılar, çünkü bu gerçekten güvenilir bir süreç değildir. – loodakrawa

cevap

0

Eğer ref veya bu yöntem değeri tarafından diyoruz çağırdığınızda param dışarı

bu değişiklik daha sonra o

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

düzeltmek edilebilir sahiptir ref dönüş yöntemini çağırın edemez