2017-08-29 19 views
8

Tôi đã thử nghiệm các tính năng C# 7 mới và tôi đã tìm thấy điều gì đó kỳ lạ. Với kịch bản đơn giản sau đây:Tại sao không thể trả về chuỗi ref nếu phương thức bên trong cũng chấp nhận các tham số trong C# 7?

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

Tại sao phương pháp thứ hai lại cho tôi lỗi trình biên dịch sau?

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

Tôi biết trình biên dịch không thể cho phép bạn quay trở lại một ref đến một var rằng có thể sẽ bị chết sau này, nhưng tôi không thực sự xem làm thế nào có thêm ra param thay đổi kịch bản này trong bất kỳ đường.

+8

Đó là một vấn đề trình biên dịch chung gọi là "con trỏ răng cưa". Loại vấn đề mà trình tối ưu hóa trong trình biên dịch C hoặc C++ phải giải quyết và có xu hướng flub. Vấn đề cơ bản là đối số 'out' cho phép một hiệu ứng phụ quan sát có thể làm mất hiệu lực tham chiếu. Chứng minh rằng chẳng hạn như nhiệm vụ không làm mất hiệu lực cmd là rất khó thực hiện. Và trên thực tế, cmd không còn tham chiếu đến các lệnh [index] nữa. Bạn sẽ nói "không có vấn đề" trong trường hợp này, trình biên dịch C# nói "không chắc chắn như vậy, chúng ta không phải". Nếu không, những lý do cơ bản tại sao Fortran vẫn có liên quan và tại sao phải mất một thời gian dài để ref được thêm vào. –

+1

Gotcha. Vì vậy, về cơ bản có các kịch bản có tham số ngoài có thể làm mất hiệu lực tham chiếu về sau để trình biên dịch làm cho tất cả các phương pháp đó bất hợp pháp thay vì cố gắng phân tích chúng bởi vì nó không thực sự là một quá trình đáng tin cậy. – loodakrawa

Trả lời

0

bạn không thể gọi phương thức hoàn trả ref có ref hoặc ra param

sự thay đổi này có thể được sửa chữa nó

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

sau đó khi bạn gọi phương thức này gọi nó bằng giá trị

Các vấn đề liên quan