2011-07-22 43 views
7

Xét đoạn mã sau đoạn mãđại biểu hiệp phương sai và Contavariance

namespace ConsoleApplication1 
{ 

public delegate TResult Function<in T, out TResult>(T args); 

class Program 
{ 
     static void Main(string[] args) 
    { 
     Program pg =new Program(); 
     Function<Object, DerivedClass> fn1 = null; 
     Function<String, BaseClass> fn2 = null; 
     fn1 = new Function<object, DerivedClass>(pg.myCheckFuntion) 
     fn2=fn1; 
     fn2("");// calls myCheckFuntion(Object a) 
     pg.myCheckFuntion("Hello"); //calls myCheckFuntion(String a) 
    } 

    public DerivedClass myCheckFuntion(Object a) 
    { 
     return new DerivedClass(); 
    } 
    public DerivedClass myCheckFuntion(String a) 
    { 
     return new DerivedClass(); 
    } 
} 

tại sao gọi đại biểu và gọi phương thức gọi phương pháp khác nhau bình thường.

Trả lời

8

Đại biểu được liên kết với myCheckFuntion(Object) lúc biên dịch - bạn đang yêu cầu họ tìm phương thức chấp nhận Object. Ràng buộc đó chỉ là một phương thức duy nhất - nó không thực hiện độ phân giải quá tải tại thời gian thực thi dựa trên kiểu đối số thực tế.

Khi bạn gọi pg.myCheckFuntion("Hello")rằng sẽ liên kết với myCheckFuntion(String) tại thời gian biên dịch vì "Hello" là một chuỗi, và việc chuyển đổi từ chuỗi chuỗi được ưa thích hơn việc chuyển đổi từ chuỗi phản đối ở độ phân giải quá tải.

Lưu ý rằng nếu bạn viết:

object text = "Hello"; 
pg.myCheckFuntion(text); 

sau đó rằng sẽ gọi myCheckFuntion(Object).

+0

Không có gì để thêm. +1 –

+0

Bạn không thể đánh bại Jon Skeet! – siride

+0

Quá nhanh đối với tôi: ( – VMAtm

1

Đối tượng đại biểu chính nó vẫn chỉ trỏ đến một chức năng, không chỉ cho một loạt các chức năng. Phương thức co (ntra) chỉ cho phép bạn trỏ nó vào một miền lớn hơn của các kiểu hàm. Trong cùng một cách, bạn có thể chỉ định tất cả các loại giá trị cho một biến loại object, nhưng ít hơn cho một biến loại string. Mặc dù vậy, một biến sẽ vẫn chỉ có một loại thực tế và một giá trị thực tại bất kỳ thời điểm nào.

2

fn2 gọi myCheckFuntion(Object a) vì tuyên bố của nó:

fn1 = new Function<object, DerivedClass>(pg.myCheckFuntion) 
fn2 = fn1; // here you copy the reference 

pg.myCheckFuntion("Hello"); gọi myCheckFuntion(Object a)String là loại hạn chế hơn object.

nếu bạn cast chuỗi Object:

pg.myCheckFuntion((object)"Hello"); 

nó sẽ gọi phương thức khác.

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