2009-09-30 31 views
5

Khi đối số chính thức của một phương thức thuộc loại 'đối tượng', có thể, thông qua kế thừa, cho đối số thực là bất kỳ loại đối tượng nào. Một khi trong phương thức, đối tượng có thể được truyền tới kiểu mong đợi. Tất cả đều ổn.Đối tượng, tham số và từ khóa ref trong C#

Tuy nhiên, nếu chữ ký của phương pháp này có một cuộc tranh luận chính thức về 'đối tượng', sử dụng từ khóa ref tức methodname (object ref), trình biên dịch ném một lỗi nói rằng:

"Phương pháp quá tải tốt nhất phù hợp cho 'ByRefTest.Program.changeMeByRef (đối tượng ref)' có một số đối số không hợp lệ. "Đối số '1': không thể chuyển đổi từ 'ref ByRefTest.Person' thành 'ref object'"

Sự khác biệt giữa việc sử dụng hay không sử dụng ref keword khi truyền các đối tượng khi các tham số được giải thích rất rõ trong blog của A. Friedman http://crazorsharp.blogspot.com/2009/07/passing-objects-using-ref-keywordwait.html, nhưng tại sao không thể chuyển kiểu tùy chỉnh thành đối số thực tế khi đối số chính thức của loại 'đối tượng' sử dụng từ khóa ref?

Như một ví dụ:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p = new Person(); 

     changeMe(p); // compiles 
     changeMeByRef(ref p); // throws error 

     object pObject = (object)p; 
     changeMeByRef(ref pObject); // compiles 
    } 


    public static void changeMeByRef(ref object obj) 
    { 
     Person p = (Person)obj; 
    } 

    public static void changeMe(object obj) 
    { 
     Person p = (Person)obj; 

    } 
} 

public class Person 
{ 
} 

Cảm ơn.

ps Tôi chỉ thay đổi chữ ký để:

public static void changeMeByRef <T> (ref T obj) nơi T: Người

này biên dịch cho changeMeByRef (ref p);

+0

Đây là bản sao của http://stackoverflow.com/questions/1207144/c-why-doesnt-ref-and-out-support-polymorphism/1207302#1207302 –

Trả lời

8

Vì phương pháp có thể thay đổi tham số để có giá trị loại khác, vi phạm loại biến được sử dụng cho đối số. Ví dụ đơn giản:

public void Foo(ref object x) 
{ 
    x = "hello"; 
} 

... 

// This doesn't compile, fortunately. 
Stream y = null; 
Foo(ref y); 

Giá trị của y sau khi chuyển nhượng trong phương thức là gì? Nó phải là một chuỗi - nhưng điều đó vi phạm loại biến. Đó sẽ là một điều rất tồi tệ, hoàn toàn vi phạm loại an toàn. Đây là cùng một loại lý do cho sự bất biến chung của IList<T> ngay cả trong .NET 4.0.

Eric Lippert recently blogged about the invariance of ref in more detail.

2

Do tham số ref hoạt động theo cả hai cách. Bạn có thể gán tham số cho một đối tượng tùy ý bên trong hàm của bạn và mã gọi cần xử lý nó.

0

làm điều này. nó dễ hơn.
changeMe (p); // biên dịch
changeMeByRef (ref (Object) p); // thời gian này nó không nên ném lỗi.

+0

@behrooz: Bạn đã thử cái này chưa? Bạn không thể bỏ một đối số ref. –

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